Showing preview only (275K chars total). Download the full file or copy to clipboard to get everything.
Repository: Sitoi/dailycheckin
Branch: main
Commit: 1fc86e25bf50
Files: 109
Total size: 250.5 KB
Directory structure:
gitextract_w6im42rl/
├── .github/
│ ├── ISSUE_TEMPLATE/
│ │ ├── 1_bug_report.yml
│ │ └── 2_feature_request.yml
│ └── workflows/
│ ├── docker-publish.yml
│ ├── docs-publish.yml
│ └── release-publish.yml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── Makefile
├── README.md
├── dailycheckin/
│ ├── __init__.py
│ ├── __version__.py
│ ├── acfun/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── aliyun/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── aolaxing/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── baidu/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── baiduwp/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── bilibili/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── configs.py
│ ├── enshan/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── fnnasclub/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── imaotai/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── iqiyi/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── kgqq/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── main.py
│ ├── mimotion/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── smzdm/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── tieba/
│ │ ├── __init__.py
│ │ └── main.py
│ ├── utils/
│ │ ├── __init__.py
│ │ └── message.py
│ ├── v2ex/
│ │ ├── __init__.py
│ │ └── main.py
│ └── youdao/
│ ├── __init__.py
│ └── main.py
├── docker/
│ ├── .dockerignore
│ ├── Dockerfile
│ ├── Makefile
│ ├── config.template.json
│ ├── crontab_list.sh
│ ├── default_task.sh
│ ├── docker-compose.yml
│ └── start.sh
├── docker_start.sh
├── docs/
│ ├── components/
│ │ ├── CardList.tsx
│ │ ├── counters.module.css
│ │ └── counters.tsx
│ ├── next-env.d.ts
│ ├── next.config.js
│ ├── package.json
│ ├── pages/
│ │ ├── _meta.json
│ │ ├── history.mdx
│ │ ├── index.md
│ │ ├── install/
│ │ │ ├── _meta.json
│ │ │ ├── docker.mdx
│ │ │ ├── local.mdx
│ │ │ ├── qinglong.mdx
│ │ │ └── synology.mdx
│ │ └── settings/
│ │ ├── _meta.json
│ │ ├── acfun.mdx
│ │ ├── aliyun.mdx
│ │ ├── aolaxing.mdx
│ │ ├── baidu.mdx
│ │ ├── baiduwp.mdx
│ │ ├── bilibili.mdx
│ │ ├── config.mdx
│ │ ├── enshan.mdx
│ │ ├── fnnas.mdx
│ │ ├── imaotai.mdx
│ │ ├── iqiyi.mdx
│ │ ├── kgqq.mdx
│ │ ├── mimotion.mdx
│ │ ├── notify/
│ │ │ ├── _meta.json
│ │ │ ├── bark.mdx
│ │ │ ├── coolpush.mdx
│ │ │ ├── dingtalk.mdx
│ │ │ ├── feishu.mdx
│ │ │ ├── gotify.mdx
│ │ │ ├── ntfy.mdx
│ │ │ ├── pushplus.mdx
│ │ │ ├── qmsg.mdx
│ │ │ ├── qywx.mdx
│ │ │ ├── qywxrobot.mdx
│ │ │ ├── server.mdx
│ │ │ ├── telegram.mdx
│ │ │ └── turbo.mdx
│ │ ├── smzdm.mdx
│ │ ├── tieba.mdx
│ │ ├── v2ex.mdx
│ │ └── youdao.mdx
│ ├── theme.config.tsx
│ └── tsconfig.json
├── imaotai_login.py
├── pyproject.toml
├── requirements.txt
└── setup.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/ISSUE_TEMPLATE/1_bug_report.yml
================================================
name: '🐛 签到失败 BUG'
description: '反馈一个签到失败的 BUG'
title: '[Bug] '
labels: ['🐛 Bug']
body:
- type: dropdown
attributes:
label: '💻 系统环境'
options:
- Windows
- macOS
- Ubuntu
- Other Linux
validations:
required: true
- type: dropdown
attributes:
label: '📦 部署环境'
options:
- 本地
- 青龙
- Docker
- 群晖
- 云函数
validations:
required: true
- type: textarea
attributes:
label: '🐛 问题描述'
description: 请提供一个清晰且简洁的问题描述。并贴上图片
validations:
required: true
- type: textarea
attributes:
label: '📝 运行日志'
description: 请提供运行的详细日志,隐私数据请马赛克。
================================================
FILE: .github/ISSUE_TEMPLATE/2_feature_request.yml
================================================
name: '🌠 功能需求'
description: '提出需求或建议'
title: '[Request] '
labels: ['🌠 功能需求']
body:
- type: textarea
attributes:
label: '🥰 需求描述'
description: 请添加一个清晰且简洁的问题描述,阐述您希望通过这个功能需求解决的问题。
validations:
required: true
- type: textarea
attributes:
label: '🧐 解决方案'
description: 请清晰且简洁地描述您想要的解决方案。例如:已有的签到脚本代码。
validations:
required: true
- type: textarea
attributes:
label: '📝 补充信息'
description: 在这里添加关于问题的任何其他背景信息。
================================================
FILE: .github/workflows/docker-publish.yml
================================================
name: Docker Push
on:
workflow_dispatch:
jobs:
docker:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: '{{defaultContext}}:docker'
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
push: true
tags: sitoi/dailycheckin:latest
================================================
FILE: .github/workflows/docs-publish.yml
================================================
name: Deploy
on:
push:
paths:
- 'docs/**'
defaults:
run:
shell: bash
working-directory: ./docs
jobs:
github_pages_deploy:
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@0.9.1
- uses: actions/checkout@v3
- name: Use Node.js 20.x
uses: actions/setup-node@v3
with:
node-version: 20.x
- name: Install dependencies
run: |
npm install
npm run export
- name: Deploy with gh-pages
run: |
git remote set-url origin https://git:${GITHUB_TOKEN}@github.com/${GITHUB_REPOSITORY}.git
npm run deploy -- -u "github-actions-bot <support+actions@github.com>"
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
================================================
FILE: .github/workflows/release-publish.yml
================================================
# This workflow will upload a Python Package using Twine when a release is published
# For more information see: https://packaging.python.org/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
name: Upload Release to PyPi
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
permissions:
id-token: write
environment:
name: pypi
url: https://pypi.org/p/dailycheckin
steps:
- uses: actions/checkout@v4
- name: Set up Python 3.9
uses: actions/setup-python@v6
with:
python-version: 3.9
- name: Install pypa/build
run: python -m pip install build --user
- name: Build a binary wheel and a source tarball
run: python -m build --sdist --wheel --outdir dist/ .
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true
# password: ${{ secrets.PYPI_API_TOKEN }}
================================================
FILE: .gitignore
================================================
# Created by .ignore support plugin (hsz.mobi)
### Python template
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
.idea
config.json
.next
node_modules
.DS_Store
================================================
FILE: .pre-commit-config.yaml
================================================
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: check-added-large-files
args: [--maxkb=100000]
- id: check-json
exclude: .vscode
- id: check-case-conflict
- id: detect-private-key
- id: mixed-line-ending
- id: trailing-whitespace
- id: fix-encoding-pragma
args:
- --remove
- id: requirements-txt-fixer
- id: trailing-whitespace
- repo: https://github.com/asottile/pyupgrade
rev: v3.20.0
hooks:
- id: pyupgrade
args: [--py39-plus]
- repo: https://github.com/MarcoGorelli/auto-walrus
rev: 0.3.4
hooks:
- id: auto-walrus
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.12.1
hooks:
- id: ruff-check
args: [--fix]
- id: ruff-format
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Sitoi
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Makefile
================================================
.PHONY: clean sdist upload pre-commit mkdocs
sdist: clean
python3 setup.py sdist bdist_wheel --universa
upload: clean
python3 setup.py upload
clean:
rm -rf build dailycheckin.egg-info dist
pre-commit:
pre-commit run --all-files
================================================
FILE: README.md
================================================
<div align="center">
<img src="https://socialify.git.ci/Sitoi/dailycheckin/image?font=Rokkitt&forks=1&issues=1&language=1&name=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Dark">
<h1>DailyCheckIn</h1>
基于「Docker」/「青龙面板」/「群晖」/「本地」的每日签到脚本
<!-- SHIELD GROUP -->
<div id="shield">
[![][github-releases-shield]][github-releases-link]
[![][pypi-version-shield]][pypi-version-link]
[![][github-release-date-shield]][github-release-date-link]
[![][github-stars-shield]][github-stars-link]
[![][github-forks-shield]][github-forks-link]
[![][github-issues-shield]][github-issues-link]
[![][github-contributors-shield]][github-contributors-link]
[![][python-version-shield]][python-version-link]
[![][pypi-dm-shield]][pypi-dm-link]
[![][docker-pull-shield]][docker-pull-link]
[![][docker-size-shield]][docker-size-link]
[![][docker-stars-shield]][docker-stars-link]
[![][github-license-shield]][github-license-link]
<!-- SHIELD GROUP -->
</div>
</div>
## ✨ 特性
- 📦 支持 Pypi 包安装
- 💻 支持多个平台部署
- ⚙️ 支持多个平台签到
- 📢 支持多个平台通知
- ♾️ 支持多个账号签到
- 🕙 支持定时任务设置
- 🆙 支持项目自动更新
## 🦄 教程
[https://sitoi.github.io/dailycheckin/](https://sitoi.github.io/dailycheckin/)
## 🧾 列表
🟢: 正常运行 🔴: 脚本暂不可用 🔵: 可以执行(需更新) 🟡: 待测试 🟤: 看脸
| 状态 | 任务名称 | 名称网站 | 检查日期 | 备注 |
| ---- | --------- | ---------------------------------------------------------- | -------- | ---------------------------------------------------------------------------- |
| 🟢️ | KGQQ | [全民 K 歌](https://kg.qq.com/index-pc.html) | 25.09.28 | 每日签到获取鲜花 每日大约 120 鲜花左右 |
| 🟢️ | YOUDAO | [有道云笔记](https://note.youdao.com/web/) | 25.09.28 | 每日签到获取存储空间 |
| 🟢️ | TIEBA | [百度贴吧](https://tieba.baidu.com/index.html) | 25.09.28 | 贴吧每日签到 |
| 🟢️ | BAIDUWP | [百度网盘](https://pan.baidu.com/wap/svip/growth/task) | 25.09.28 | 百度网盘会员签到和答题功能 |
| 🟢️ | BILIBILI | [BiliBili](https://www.bilibili.com/) | 25.09.28 | 漫画签到,每日经验任务,自动投币,银瓜子换硬币等功能 |
| 🟢️ | V2EX | [V2EX](https://www.v2ex.com/) | 25.09.28 | 铜币奖励 |
| 🟢️ | ACFUN | [AcFun](https://www.acfun.cn/) | 25.09.28 | 每日签到香蕉 |
| 🟢️ | IQIYI | [爱奇艺](https://www.iqiyi.com/) | 25.09.28 | ① VIP7 每月免费领白金会员;② 抽白金会员 5 次;③ 摇一摇抽奖 3 次;④ 抽奖 3 次 |
| 🟢️ | SMZDM | [什么值得买](https://www.smzdm.com/) | 24.02.20 | 签到和抽奖 |
| 🟢️ | ALIYUN | [阿里云盘](https://www.aliyundrive.com/drive/) | 24.02.20 | 签到获取免费会员和空间 |
| 🟢️ | ENSHAN | [恩山无线论坛](https://www.right.com.cn/forum/) | 24.02.20 | 签到获取硬币和积分 |
| 🟢️ | FNNASCLUB | [飞牛 Nas](https://club.fnnas.com/) | 25.12.09 | 签到奖励 |
| 🟢️ | AOLAXING | [奥拉星](http://www.100bt.com/m/creditMall/?gameId=2#task) | 24.02.20 | 签到获取积分 |
| 🟢️ | IMAOTAI | i 茅台 | 25.09.28 | 申购生肖茅台 |
| 🟤 | MIMOTION | 小米运动 | 25.09.28 | 每日小米运动刷步数 |
| 🟢️ | BAIDU | [百度站点](https://ziyuan.baidu.com/site/index#/) | 25.09.28 | 提交网站页面供百度收录 |
## 💬 通知列表
- dingtalk(钉钉)
- 企业微信群机器人(企业微信)
- 企业微信应用消息(企业微信)
- telegram(TG)
- Bark(iOS)
- server 酱(微信)
- server 酱 TURBO(微信)
- pushplus(微信)
- Cool Push(QQ,微信,邮箱)
- qmsg 酱(QQ)
- 飞书(飞书)
## 🤝 参与贡献
我们非常欢迎各种形式的贡献。如果你对贡献代码感兴趣,可以查看我们的 GitHub [Issues][github-issues-link],大展身手,向我们展示你的奇思妙想。
[![][pr-welcome-shield]][pr-welcome-link]
### 💗 感谢我们的贡献者
[![][github-contrib-shield]][github-contrib-link]
## ✨ Star 数
[![][starchart-shield]][starchart-link]
---
## 📝 License
Copyright © 2021 [Sitoi][profile-link]. <br />
This project is [MIT](https://github.com/Sitoi/dailycheckin/blob/main/LICENSE) licensed.
<!-- LINK GROUP -->
[profile-link]: https://github.com/sitoi
[github-codespace-link]: https://codespaces.new/sitoi/dailycheckin
[github-codespace-shield]: https://github.com/sitoi/dailycheckin/blob/main/images/codespaces.png?raw=true
[github-contributors-link]: https://github.com/sitoi/dailycheckin/graphs/contributors
[github-contributors-shield]: https://img.shields.io/github/contributors/sitoi/dailycheckin?color=c4f042&labelColor=black&style=flat-square
[github-forks-link]: https://github.com/sitoi/dailycheckin/network/members
[github-forks-shield]: https://img.shields.io/github/forks/sitoi/dailycheckin?color=8ae8ff&labelColor=black&style=flat-square
[github-issues-link]: https://github.com/sitoi/dailycheckin/issues
[github-issues-shield]: https://img.shields.io/github/issues/sitoi/dailycheckin?color=ff80eb&labelColor=black&style=flat-square
[github-license-link]: https://github.com/sitoi/dailycheckin/blob/main/LICENSE
[github-license-shield]: https://img.shields.io/github/license/sitoi/dailycheckin?labelColor=black&style=flat-square
[github-stars-link]: https://github.com/sitoi/dailycheckin/stargazers
[github-stars-shield]: https://img.shields.io/github/stars/sitoi/dailycheckin?color=ffcb47&labelColor=black&style=flat-square
[github-releases-link]: https://github.com/sitoi/dailycheckin/releases
[github-releases-shield]: https://img.shields.io/github/v/release/sitoi/dailycheckin?labelColor=black&style=flat-square
[github-release-date-link]: https://github.com/sitoi/dailycheckin/releases
[github-release-date-shield]: https://img.shields.io/github/release-date/sitoi/dailycheckin?labelColor=black&style=flat-square
[pr-welcome-link]: https://github.com/sitoi/dailycheckin/pulls
[pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge
[github-contrib-link]: https://github.com/sitoi/dailycheckin/graphs/contributors
[github-contrib-shield]: https://contrib.rocks/image?repo=sitoi%2Fdailycheckin
[docker-pull-shield]: https://img.shields.io/docker/pulls/sitoi/dailycheckin?labelColor=black&style=flat-square
[docker-pull-link]: https://hub.docker.com/repository/docker/sitoi/dailycheckin
[docker-size-shield]: https://img.shields.io/docker/image-size/sitoi/dailycheckin?labelColor=black&style=flat-square
[docker-size-link]: https://hub.docker.com/repository/docker/sitoi/dailycheckin
[docker-stars-shield]: https://img.shields.io/docker/stars/sitoi/dailycheckin?labelColor=black&style=flat-square
[docker-stars-link]: https://hub.docker.com/repository/docker/sitoi/dailycheckin
[pypi-dm-shield]: https://img.shields.io/pypi/dm/dailycheckin?label=pypi&labelColor=black&style=flat-square
[pypi-dm-link]: https://pypi.org/project/dailycheckin/
[python-version-link]: https://pypi.org/project/dailycheckin/
[python-version-shield]: https://img.shields.io/pypi/pyversions/dailycheckin?labelColor=black&style=flat-square
[pypi-version-shield]: https://img.shields.io/pypi/v/dailycheckin?labelColor=black&style=flat-square
[pypi-version-link]: https://pypi.org/project/dailycheckin/
[starchart-shield]: https://api.star-history.com/svg?repos=sitoi/dailycheckin&type=Date
[starchart-link]: https://star-history.com/#sitoi/dailycheckin&Date
================================================
FILE: dailycheckin/__init__.py
================================================
import pkgutil as _pkgutil
class CheckIn:
name = "Base"
__path__ = _pkgutil.extend_path(__path__, __name__)
for _, _modname, _ in _pkgutil.walk_packages(path=__path__, prefix=__name__ + "."):
if _modname not in ["dailycheckin.main", "dailycheckin.configs"]:
__import__(_modname)
================================================
FILE: dailycheckin/__version__.py
================================================
__version__ = "25.12.9"
================================================
FILE: dailycheckin/acfun/__init__.py
================================================
================================================
FILE: dailycheckin/acfun/main.py
================================================
import json
import os
import re
import requests
import urllib3
from dailycheckin import CheckIn
urllib3.disable_warnings()
class AcFun(CheckIn):
name = "AcFun"
def __init__(self, check_item: dict):
self.check_item = check_item
self.contentid = "27259341"
self.st = None
@staticmethod
def login(phone, password, session):
url = "https://id.app.acfun.cn/rest/web/login/signin"
body = f"username={phone}&password={password}&key=&captcha="
res = session.post(url=url, data=body).json()
return (True, res) if res.get("result") == 0 else (False, res.get("err_msg"))
@staticmethod
def get_cookies(session, phone, password):
url = "https://id.app.acfun.cn/rest/app/login/signin"
headers = {
"Host": "id.app.acfun.cn",
"user-agent": "AcFun/6.39.0 (iPhone; iOS 14.3; Scale/2.00)",
"devicetype": "0",
"accept-language": "zh-Hans-CN;q=1, en-CN;q=0.9, ja-CN;q=0.8, zh-Hant-HK;q=0.7, io-Latn-CN;q=0.6",
"accept": "application/json",
"content-type": "application/x-www-form-urlencoded",
}
data = f"password={password}&username={phone}"
response = session.post(url=url, data=data, headers=headers, verify=False)
acpasstoken = response.json().get("acPassToken")
auth_key = str(response.json().get("auth_key"))
if acpasstoken and auth_key:
cookies = {"acPasstoken": acpasstoken, "auth_key": auth_key}
return cookies
else:
return False
def get_token(self, session):
url = "https://id.app.acfun.cn/rest/web/token/get?sid=acfun.midground.api"
res = session.post(url=url).json()
self.st = res.get("acfun.midground.api_st") if res.get("result") == 0 else ""
return self.st
def get_video(self, session):
url = "https://www.acfun.cn/rest/pc-direct/rank/channel"
res = session.get(url=url).json()
self.contentid = res.get("rankList")[0].get("contentId")
return self.contentid
@staticmethod
def sign(session):
url = "https://www.acfun.cn/rest/pc-direct/user/signIn"
response = session.post(url=url)
return {"name": "签到信息", "value": response.json().get("msg")}
def danmu(self, session):
url = "https://www.acfun.cn/rest/pc-direct/new-danmaku/add"
data = {
"mode": "1",
"color": "16777215",
"size": "25",
"body": "123321",
"videoId": "26113662",
"position": "2719",
"type": "douga",
"id": "31224739",
"subChannelId": "1",
"subChannelName": "动画",
}
response = session.get(url=f"https://www.acfun.cn/v/ac{self.contentid}")
video_id = re.findall(r'"currentVideoId":(\d+),', response.text)
sub_channel = re.findall(r'{subChannelId:(\d+),subChannelName:"([\u4e00-\u9fa5]+)"}', response.text)
if video_id:
data["videoId"] = video_id[0]
data["subChannelId"] = sub_channel[0][0]
data["subChannelName"] = sub_channel[0][1]
res = session.post(url=url, data=data).json()
msg = "弹幕成功" if res.get("result") == 0 else "弹幕失败"
return {"name": "弹幕任务", "value": msg}
def throwbanana(self, session):
url = "https://www.acfun.cn/rest/pc-direct/banana/throwBanana"
data = {"resourceId": self.contentid, "count": "1", "resourceType": "2"}
res = session.post(url=url, data=data).json()
msg = "投🍌成功" if res.get("result") == 0 else "投🍌失败"
return {"name": "香蕉任务", "value": msg}
def like(self, session):
like_url = "https://kuaishouzt.com/rest/zt/interact/add"
unlike_url = "https://kuaishouzt.com/rest/zt/interact/delete"
body = (
f"kpn=ACFUN_APP&kpf=PC_WEB&subBiz=mainApp&interactType=1&"
f"objectType=2&objectId={self.contentid}&acfun.midground.api_st={self.st}&"
f"extParams%5BisPlaying%5D=false&extParams%5BshowCount%5D=1&extParams%5B"
f"otherBtnClickedCount%5D=10&extParams%5BplayBtnClickedCount%5D=0"
)
res = session.post(url=like_url, data=body).json()
session.post(url=unlike_url, data=body)
msg = "点赞成功" if res.get("result") == 1 else "点赞失败"
return {"name": "点赞任务", "value": msg}
def share(self, session, cookies):
url = "https://api-ipv6.acfunchina.com/rest/app/task/reportTaskAction?taskType=1&market=tencent&product=ACFUN_APP&appMode=0"
headers = {
"Content-Type": "application/x-www-form-urlencoded",
}
response = session.get(url=url, headers=headers, cookies=cookies, verify=False)
if response.json().get("result") == 0:
msg = "分享成功"
else:
msg = "分享失败"
return {"name": "分享任务", "value": msg}
@staticmethod
def get_info(session):
url = "https://www.acfun.cn/rest/pc-direct/user/personalInfo"
res = session.get(url=url).json()
if res.get("result") != 0:
return [{"name": "当前等级", "value": "查询失败"}]
info = res.get("info")
return [
{"name": "当前等级", "value": info.get("level")},
{"name": "持有香蕉", "value": info.get("banana")},
]
def main(self):
phone = self.check_item.get("phone")
password = self.check_item.get("password")
session = requests.session()
session.headers.update(
{
"accept": "*/*",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"content-type": "application/x-www-form-urlencoded; charset=UTF-8",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70",
"Referer": "https://www.acfun.cn/",
}
)
flag, res = self.login(phone, password, session)
if flag is True:
self.get_video(session=session)
self.get_token(session=session)
sign_msg = self.sign(session=session)
like_msg = self.like(session=session)
danmu_msg = self.danmu(session=session)
throwbanana_msg = self.throwbanana(session=session)
info_msg = self.get_info(session=session)
msg = [
{"name": "帐号信息", "value": phone},
sign_msg,
like_msg,
danmu_msg,
throwbanana_msg,
*info_msg,
]
else:
msg = [
{"name": "帐号信息", "value": phone},
{"name": "错误信息", "value": res},
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("ACFUN", [])[0]
print(AcFun(check_item=_check_item).main())
================================================
FILE: dailycheckin/aliyun/__init__.py
================================================
================================================
FILE: dailycheckin/aliyun/main.py
================================================
import json
import os
import requests
import urllib3
from dailycheckin import CheckIn
urllib3.disable_warnings()
class AliYun(CheckIn):
name = "阿里云盘"
def __init__(self, check_item: dict):
self.check_item = check_item
def update_token(self, refresh_token):
url = "https://auth.aliyundrive.com/v2/account/token"
data = {"grant_type": "refresh_token", "refresh_token": refresh_token}
response = requests.post(url=url, json=data).json()
access_token = response.get("access_token")
return access_token
def sign(self, access_token):
url = "https://member.aliyundrive.com/v1/activity/sign_in_list"
headers = {"Authorization": access_token, "Content-Type": "application/json"}
result = requests.post(url=url, headers=headers, json={}).json()
sign_days = result["result"]["signInCount"]
data = {"signInDay": sign_days}
url_reward = "https://member.aliyundrive.com/v1/activity/sign_in_reward"
requests.post(url=url_reward, headers=headers, data=json.dumps(data))
if "success" in result:
print("签到成功")
for i, j in enumerate(result["result"]["signInLogs"]):
if j["status"] == "miss":
day_json = result["result"]["signInLogs"][i - 1]
if not day_json["isReward"]:
msg = [
{
"name": "阿里云盘",
"value": "签到成功,今日未获得奖励",
}
]
else:
msg = [
{
"name": "累计签到",
"value": result["result"]["signInCount"],
},
{
"name": "阿里云盘",
"value": "获得奖励:{}{}".format(
day_json["reward"]["name"],
day_json["reward"]["description"],
),
},
]
return msg
def main(self):
refresh_token = self.check_item.get("refresh_token")
access_token = self.update_token(refresh_token)
if not access_token:
return [{"name": "阿里云盘", "value": "token 过期"}]
msg = self.sign(access_token)
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("ALIYUN", [])[0]
print(AliYun(check_item=_check_item).main())
================================================
FILE: dailycheckin/aolaxing/__init__.py
================================================
================================================
FILE: dailycheckin/aolaxing/main.py
================================================
import json
import os
import time
import requests
from dailycheckin import CheckIn
class AoLaXing(CheckIn):
name = "奥拉星"
def __init__(self, check_item: dict):
self.check_item = check_item
def user(self, headers):
url = "http://service.100bt.com/creditmall/my/user_info.jsonp"
user_json = requests.get(url, headers=headers).json()
user_data = user_json["jsonResult"]["data"]
try:
credit = user_data["credit"]
credit_history = user_data["creditHistory"]
phone_num = user_data["phoneNum"]
signin_total = user_data["signInTotal"]
except Exception as e:
return [{"name": "签到", "value": str(e)}]
msgs = [
{"name": "用户", "value": phone_num},
{"name": "当前积分", "value": credit},
{"name": "总共获得积分", "value": credit_history},
{"name": "总签到", "value": signin_total},
]
return msgs
def practise(self, headers, task_id):
url = f"http://service.100bt.com/creditmall/activity/do_task.jsonp?taskId={task_id}&gameId=2&_=1643440166690"
task_json = requests.get(url, headers=headers).json()
try:
message = task_json["jsonResult"]["message"]
except Exception:
message = "NO"
return message
def task(self, headers, msg: bool = False):
url = "http://service.100bt.com/creditmall/activity/daily_task_list.jsonp?gameId=2&_=1643437206026"
task_json = requests.get(url, headers=headers).json()
task_data = task_json["jsonResult"]["data"]
task_finish_count = 0
for task_item in task_data:
name = task_item["name"]
status_desc = task_item["status_desc"]
task_id = task_item["taskID"]
if msg:
if status_desc == "已完成":
task_finish_count += 1
elif status_desc == "未完成":
print(f"开始任务:{name}")
res = self.practise(task_id=task_id, headers=headers)
print(f"返回状态:{res}")
time.sleep(2.5)
msgs = [
{"name": "今日任务总数", "value": len(task_data)},
{"name": "今日任务完成数", "value": task_finish_count},
]
return msgs
def main(self):
cookie = self.check_item.get("cookie")
headers = {
"Host": "service.100bt.com",
"Proxy-Connection": "keep-alive",
"Accept": "*/*",
"Referer": "http://www.100bt.com/",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9",
"Cookie": cookie,
}
_ = self.task(headers)
task_msgs = self.task(headers=headers, msg=True)
user_msgs = self.user(headers=headers)
msgs = task_msgs + user_msgs
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msgs])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("AOLAXING", [])[0]
print(AoLaXing(check_item=_check_item).main())
================================================
FILE: dailycheckin/baidu/__init__.py
================================================
================================================
FILE: dailycheckin/baidu/main.py
================================================
import json
import os
from urllib import parse
import requests
from dailycheckin import CheckIn
class Baidu(CheckIn):
name = "百度站点提交"
def __init__(self, check_item: dict):
self.check_item = check_item
@staticmethod
def url_submit(data_url: str, submit_url: str, times: int = 100) -> str:
site = parse.parse_qs(parse.urlsplit(submit_url).query).get("site")[0]
urls_data = requests.get(url=data_url)
remain = 100000
success_count = 0
error_count = 0
for one in range(times):
try:
response = requests.post(url=submit_url, data=urls_data)
if response.json().get("success"):
remain = response.json().get("remain")
success_count += response.json().get("success")
else:
error_count += 1
except Exception as e:
print(e)
error_count += 1
msg = [
{"name": "站点地址", "value": site},
{"name": "剩余条数", "value": remain},
{"name": "成功条数", "value": success_count},
{"name": "成功次数", "value": times - error_count},
{"name": "失败次数", "value": error_count},
]
return msg
def main(self):
data_url = self.check_item.get("data_url")
submit_url = self.check_item.get("submit_url")
times = int(self.check_item.get("times", 100))
if data_url and submit_url:
msg = self.url_submit(data_url=data_url, submit_url=submit_url, times=times)
else:
msg = {"name": "站点配置", "value": "配置错误"}
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("BAIDU", [])[0]
print(Baidu(check_item=_check_item).main())
================================================
FILE: dailycheckin/baiduwp/__init__.py
================================================
================================================
FILE: dailycheckin/baiduwp/main.py
================================================
import json
import os
import re
import time
import requests
from dailycheckin import CheckIn
class BaiduWP(CheckIn):
name = "百度网盘"
"""
百度网盘会员成长值签到和答题功能。
传入cookie 自动完成签到、答题和会员信息查询。
"""
def __init__(self, check_item: dict):
self.cookie = check_item.get("cookie")
self.session = requests.Session()
self.headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 11; Pixel 5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.91 Mobile Safari/537.36",
"Referer": "https://pan.baidu.com/wap/svip/growth/task",
"Accept": "application/json, text/plain, */*",
"X-Requested-With": "XMLHttpRequest",
"Connection": "keep-alive",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": self.cookie,
}
def signin(self):
url = "https://pan.baidu.com/rest/2.0/membership/level?app_id=250528&web=5&method=signin"
resp = self.session.get(url, headers=self.headers)
sign_point = None
signin_error_msg = ""
if resp.status_code == 200:
m = re.search(r'points":(\d+)', resp.text)
if m:
sign_point = m.group(1)
m2 = re.search(r'"error_msg":"(.*?)",', resp.text)
if m2:
signin_error_msg = m2.group(1)
else:
signin_error_msg = f"签到请求失败: {resp.status_code} {self.cookie}"
return sign_point, signin_error_msg
def get_question(self):
url = "https://pan.baidu.com/act/v2/membergrowv2/getdailyquestion?app_id=250528&web=5"
resp = self.session.get(url, headers=self.headers)
answer = None
ask_id = None
if resp.status_code == 200:
m = re.search(r'"answer":(\d+),', resp.text)
if m:
answer = m.group(1)
m2 = re.search(r'"ask_id":(\d+),', resp.text)
if m2:
ask_id = m2.group(1)
return ask_id, answer
def answer_question(self, ask_id, answer):
url = f"https://pan.baidu.com/act/v2/membergrowv2/answerquestion?app_id=250528&web=5&ask_id={ask_id}&answer={answer}"
resp = self.session.get(url, headers=self.headers)
answer_score = None
answer_msg = ""
if resp.status_code == 200:
m = re.search(r'"score":(\d+)', resp.text)
if m:
answer_score = m.group(1)
m2 = re.search(r'"show_msg":"(.*?)"', resp.text)
if m2:
answer_msg = m2.group(1)
return answer_score, answer_msg
def get_userinfo(self):
url = "https://pan.baidu.com/rest/2.0/membership/user?app_id=250528&web=5&method=query"
resp = self.session.get(url, headers=self.headers)
current_value = None
current_level = None
if resp.status_code == 200:
m = re.search(r'current_value":(\d+),', resp.text)
if m:
current_value = m.group(1)
m2 = re.search(r'current_level":(\d+),', resp.text)
if m2:
current_level = m2.group(1)
return current_level, current_value
def main(self):
sign_point, signin_error_msg = self.signin()
time.sleep(3)
ask_id, answer = self.get_question()
answer_score, answer_msg = (None, "")
if ask_id and answer:
answer_score, answer_msg = self.answer_question(ask_id, answer)
current_level, current_value = self.get_userinfo()
msg = f"签到获得{sign_point or ''}{signin_error_msg}\n答题获得{answer_score or ''}{answer_msg}\n当前会员等级{current_level or ''},成长值{current_value or ''}"
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("BAIDUWP", [])[0]
print(BaiduWP(check_item=_check_item).main())
================================================
FILE: dailycheckin/bilibili/__init__.py
================================================
================================================
FILE: dailycheckin/bilibili/main.py
================================================
import json
import os
import time
import requests
from dailycheckin import CheckIn
class BiliBili(CheckIn):
name = "Bilibili"
def __init__(self, check_item: dict):
self.check_item = check_item
@staticmethod
def get_nav(session):
url = "https://api.bilibili.com/x/web-interface/nav"
ret = session.get(url=url).json()
uname = ret.get("data", {}).get("uname")
uid = ret.get("data", {}).get("mid")
is_login = ret.get("data", {}).get("isLogin")
coin = ret.get("data", {}).get("money")
vip_type = ret.get("data", {}).get("vipType")
current_exp = ret.get("data", {}).get("level_info", {}).get("current_exp")
return uname, uid, is_login, coin, vip_type, current_exp
@staticmethod
def get_today_exp(session: requests.Session) -> list:
"""GET 获取今日经验信息
:param requests.Session session:
:return list: 今日经验信息列表
"""
url = "https://api.bilibili.com/x/member/web/exp/log?jsonp=jsonp"
today = time.strftime("%Y-%m-%d", time.localtime())
return list(
filter(
lambda x: x["time"].split()[0] == today,
session.get(url=url).json().get("data").get("list"),
)
)
@staticmethod
def vip_privilege_my(session) -> dict:
"""取B站大会员硬币经验信息"""
url = "https://api.bilibili.com/x/vip/privilege/my"
ret = session.get(url=url).json()
return ret
@staticmethod
def reward(session) -> dict:
"""取B站经验信息"""
url = "https://api.bilibili.com/x/member/web/exp/log?jsonp=jsonp"
today = time.strftime("%Y-%m-%d", time.localtime())
return list(
filter(
lambda x: x["time"].split()[0] == today,
session.get(url=url).json().get("data").get("list"),
)
)
@staticmethod
def live_sign(session) -> dict:
"""B站直播签到"""
try:
url = "https://api.live.bilibili.com/xlive/web-ucenter/v1/sign/DoSign"
ret = session.get(url=url).json()
if ret["code"] == 0:
msg = f"签到成功,{ret['data']['text']},特别信息:{ret['data']['specialText']},本月已签到{ret['data']['hadSignDays']}天"
elif ret["code"] == 1011040:
msg = "今日已签到过,无法重复签到"
else:
msg = f"签到失败,信息为: {ret['message']}"
except Exception as e:
msg = f"签到异常,原因为{e!s}"
print(msg)
return msg
@staticmethod
def manga_sign(session, platform="android") -> dict:
"""
模拟B站漫画客户端签到
"""
try:
url = "https://manga.bilibili.com/twirp/activity.v1.Activity/ClockIn"
post_data = {"platform": platform}
ret = session.post(url=url, data=post_data).json()
if ret["code"] == 0:
msg = "签到成功"
elif ret["msg"] == "clockin clockin is duplicate":
msg = "今天已经签到过了"
else:
msg = f"签到失败,信息为({ret['msg']})"
print(msg)
except Exception as e:
msg = f"签到异常,原因为: {e!s}"
print(msg)
return msg
@staticmethod
def vip_privilege_receive(session, bili_jct, receive_type: int = 1) -> dict:
"""
领取B站大会员权益
receive_type int 权益类型 1为B币劵 2为优惠券
"""
url = "https://api.bilibili.com/x/vip/privilege/receive"
post_data = {"type": receive_type, "csrf": bili_jct}
ret = session.post(url=url, data=post_data).json()
return ret
@staticmethod
def vip_manga_reward(session) -> dict:
"""获取漫画大会员福利"""
url = "https://manga.bilibili.com/twirp/user.v1.User/GetVipReward"
ret = session.post(url=url, json={"reason_id": 1}).json()
return ret
@staticmethod
def report_task(session, bili_jct, aid: int, cid: int, progres: int = 300) -> dict:
"""
B站上报视频观看进度
aid int 视频av号
cid int 视频cid号
progres int 观看秒数
"""
url = "http://api.bilibili.com/x/v2/history/report"
post_data = {"aid": aid, "cid": cid, "progres": progres, "csrf": bili_jct}
ret = session.post(url=url, data=post_data).json()
return ret
@staticmethod
def share_task(session, bili_jct, aid) -> dict:
"""
分享指定av号视频
aid int 视频av号
"""
url = "https://api.bilibili.com/x/web-interface/share/add"
post_data = {"aid": aid, "csrf": bili_jct}
ret = session.post(url=url, data=post_data).json()
return ret
@staticmethod
def get_followings(
session,
uid: int,
pn: int = 1,
ps: int = 50,
order: str = "desc",
order_type: str = "attention",
) -> dict:
"""
获取指定用户关注的up主
uid int 账户uid 默认为本账户 非登录账户只能获取20个*5页
pn int 页码 默认第一页
ps int 每页数量 默认50
order str 排序方式 默认desc
order_type 排序类型 默认attention
"""
params = {
"vmid": uid,
"pn": pn,
"ps": ps,
"order": order,
"order_type": order_type,
}
url = "https://api.bilibili.com/x/relation/followings"
ret = session.get(url=url, params=params).json()
return ret
@staticmethod
def space_arc_search(
session,
uid: int,
pn: int = 1,
ps: int = 30,
tid: int = 0,
order: str = "pubdate",
keyword: str = "",
) -> dict:
"""
获取指定up主空间视频投稿信息
uid int 账户uid 默认为本账户
pn int 页码 默认第一页
ps int 每页数量 默认50
tid int 分区 默认为0(所有分区)
order str 排序方式 默认pubdate
keyword str 关键字 默认为空
"""
params = {
"mid": uid,
"pn": pn,
"Ps": ps,
"tid": tid,
"order": order,
"keyword": keyword,
}
url = "https://api.bilibili.com/x/space/arc/search"
ret = session.get(url=url, params=params).json()
count = 2
data_list = [
{
"aid": one.get("aid"),
"cid": 0,
"title": one.get("title"),
"owner": one.get("author"),
}
for one in ret.get("data", {}).get("list", {}).get("vlist", [])[:count]
]
return data_list, count
@staticmethod
def elec_pay(session, bili_jct, uid: int, num: int = 50) -> dict:
"""
用B币给up主充电
uid int up主uid
num int 充电电池数量
"""
url = "https://api.bilibili.com/x/ugcpay/trade/elec/pay/quick"
post_data = {
"elec_num": num,
"up_mid": uid,
"otype": "up",
"oid": uid,
"csrf": bili_jct,
}
ret = session.post(url=url, data=post_data).json()
return ret
@staticmethod
def coin_add(session, bili_jct, aid: int, num: int = 1, select_like: int = 1) -> dict:
"""
给指定 av 号视频投币
aid int 视频av号
num int 投币数量
select_like int 是否点赞
"""
url = "https://api.bilibili.com/x/web-interface/coin/add"
post_data = {
"aid": aid,
"multiply": num,
"select_like": select_like,
"cross_domain": "true",
"csrf": bili_jct,
}
ret = session.post(url=url, data=post_data).json()
return ret
@staticmethod
def live_status(session) -> dict:
"""B站直播获取金银瓜子状态"""
url = "https://api.live.bilibili.com/pay/v1/Exchange/getStatus"
ret = session.get(url=url).json()
data = ret.get("data")
silver = data.get("silver", 0)
gold = data.get("gold", 0)
coin = data.get("coin", 0)
msg = [
{"name": "硬币数量", "value": coin},
{"name": "金瓜子数", "value": gold},
{"name": "银瓜子数", "value": silver},
]
return msg
@staticmethod
def get_region(session, rid=1, num=6) -> dict:
"""
获取 B站分区视频信息
rid int 分区号
num int 获取视频数量
"""
url = "https://api.bilibili.com/x/web-interface/dynamic/region?ps=" + str(num) + "&rid=" + str(rid)
ret = session.get(url=url).json()
data_list = [
{
"aid": one.get("aid"),
"cid": one.get("cid"),
"title": one.get("title"),
"owner": one.get("owner", {}).get("name"),
}
for one in ret.get("data", {}).get("archives", [])
]
return data_list
@staticmethod
def silver2coin(session, bili_jct) -> dict:
"""B站银瓜子换硬币"""
url = "https://api.live.bilibili.com/xlive/revenue/v1/wallet/silver2coin"
post_data = {"csrf": bili_jct}
ret = session.post(url=url, data=post_data).json()
return ret
def main(self):
bilibili_cookie = {item.split("=")[0]: item.split("=")[1] for item in self.check_item.get("cookie").split("; ")}
bili_jct = bilibili_cookie.get("bili_jct")
coin_num = self.check_item.get("coin_num", 0)
coin_type = self.check_item.get("coin_type", 1)
silver2coin = self.check_item.get("silver2coin", False)
session = requests.session()
requests.utils.add_dict_to_cookiejar(session.cookies, bilibili_cookie)
session.headers.update(
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.64",
"Referer": "https://www.bilibili.com/",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
"Connection": "keep-alive",
}
)
success_count = 0
uname, uid, is_login, coin, vip_type, current_exp = self.get_nav(session=session)
if is_login:
manhua_msg = self.manga_sign(session=session)
live_msg = self.live_sign(session=session)
aid_list = self.get_region(session=session)
vip_privilege_my_ret = self.vip_privilege_my(session=session)
welfare_list = vip_privilege_my_ret.get("data", {}).get("list", [])
for welfare in welfare_list:
if welfare.get("state") == 0 and welfare.get("vip_type") == vip_type:
vip_privilege_receive_ret = self.vip_privilege_receive(
session=session,
bili_jct=bili_jct,
receive_type=welfare.get("type"),
)
print(vip_privilege_receive_ret)
coins_av_count = len(
list(
filter(
lambda x: x["reason"] == "视频投币奖励",
self.get_today_exp(session=session),
)
)
)
coin_num = coin_num - coins_av_count
coin_num = coin_num if coin_num < coin else coin
if coin_type == 1:
following_list = self.get_followings(session=session, uid=uid)
count = 0
for following in following_list.get("data", {}).get("list"):
mid = following.get("mid")
if mid:
tmplist, tmpcount = self.space_arc_search(session=session, uid=mid)
aid_list += tmplist
count += tmpcount
if count > coin_num:
print("已获取足够关注用户的视频")
break
else:
aid_list += self.get_region(session=session)
for one in aid_list[::-1]:
print(one)
if coin_num > 0:
for aid in aid_list[::-1]:
ret = self.coin_add(session=session, aid=aid.get("aid"), bili_jct=bili_jct)
if ret["code"] == 0:
coin_num -= 1
print(f"成功给{aid.get('title')}投一个币")
success_count += 1
elif ret["code"] == 34005:
print(f"投币{aid.get('title')}失败,原因为{ret['message']}")
continue
# -104 硬币不够了 -111 csrf 失败 34005 投币达到上限
else:
print(f"投币{aid.get('title')}失败,原因为{ret['message']},跳过投币")
break
if coin_num <= 0:
break
coin_msg = f"今日成功投币{success_count + coins_av_count}/{self.check_item.get('coin_num', 5)}个"
else:
coin_msg = f"今日成功投币{coins_av_count}/{self.check_item.get('coin_num', 5)}个"
aid = aid_list[0].get("aid")
cid = aid_list[0].get("cid")
title = aid_list[0].get("title")
report_ret = self.report_task(session=session, bili_jct=bili_jct, aid=aid, cid=cid)
if report_ret.get("code") == 0:
report_msg = f"观看《{title}》300秒"
else:
report_msg = "任务失败"
share_ret = self.share_task(session=session, bili_jct=bili_jct, aid=aid)
if share_ret.get("code") == 0:
share_msg = f"分享《{title}》成功"
else:
share_msg = "分享失败"
print(share_msg)
s2c_msg = "不兑换硬币"
if silver2coin:
silver2coin_ret = self.silver2coin(session=session, bili_jct=bili_jct)
s2c_msg = silver2coin_ret["message"]
if silver2coin_ret["code"] != 0:
print(s2c_msg)
else:
s2c_msg = ""
live_stats = self.live_status(session=session)
uname, uid, is_login, new_coin, vip_type, new_current_exp = self.get_nav(session=session)
today_exp = sum(map(lambda x: x["delta"], self.get_today_exp(session=session)))
update_data = (28800 - new_current_exp) // (today_exp if today_exp else 1)
msg = [
{"name": "帐号信息", "value": uname},
{"name": "漫画签到", "value": manhua_msg},
{"name": "直播签到", "value": live_msg},
{"name": "登陆任务", "value": "今日已登陆"},
{"name": "观看视频", "value": report_msg},
{"name": "分享任务", "value": share_msg},
{"name": "瓜子兑换", "value": s2c_msg},
{"name": "投币任务", "value": coin_msg},
{"name": "今日经验", "value": today_exp},
{"name": "当前经验", "value": new_current_exp},
{"name": "升级还需", "value": f"{update_data}天"},
*live_stats,
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("BILIBILI", [])[0]
print(BiliBili(check_item=_check_item).main())
================================================
FILE: dailycheckin/configs.py
================================================
import json
import os
from dailycheckin import CheckIn
def checkin_map():
result = {}
for cls in CheckIn.__subclasses__():
check_name = cls.__name__.upper()
if check_name:
result[check_name] = (cls.name, cls)
return result
checkin_map = checkin_map()
notice_map = {
"BARK_URL": "",
"COOLPUSHEMAIL": "",
"COOLPUSHQQ": "",
"COOLPUSHSKEY": "",
"COOLPUSHWX": "",
"DINGTALK_ACCESS_TOKEN": "",
"DINGTALK_SECRET": "",
"FSKEY": "",
"PUSHPLUS_TOKEN": "",
"PUSHPLUS_TOPIC": "",
"QMSG_KEY": "",
"QMSG_TYPE": "",
"QYWX_AGENTID": "",
"QYWX_CORPID": "",
"QYWX_CORPSECRET": "",
"QYWX_KEY": "",
"QYWX_TOUSER": "",
"QYWX_MEDIA_ID": "",
"QYWX_ORIGIN": "",
"SCKEY": "",
"SENDKEY": "",
"TG_API_HOST": "",
"TG_BOT_TOKEN": "",
"TG_PROXY": "",
"TG_USER_ID": "",
"MERGE_PUSH": "",
"GOTIFY_URL": "",
"GOTIFY_TOKEN": "",
"GOTIFY_PRIORITY": "",
"NTFY_URL": "",
"NTFY_TOPIC": "",
"NTFY_PRIORITY": "",
}
def env2list(key):
try:
value = json.loads(os.getenv(key, []).strip()) if os.getenv(key) else []
if not isinstance(value, list):
value = []
except Exception as e:
print(e)
value = []
return value
def env2str(key):
try:
value = os.getenv(key, "") if os.getenv(key) else ""
if isinstance(value, str):
value = value.strip()
elif isinstance(value, bool):
pass
else:
value = None
except Exception as e:
print(e)
value = None
return value
def get_checkin_info(data):
result = {}
if isinstance(data, dict):
for one in checkin_map.keys():
result[one.lower()] = data.get(one, [])
else:
for one in checkin_map.keys():
result[one.lower()] = env2list(one)
return result
def get_notice_info(data):
result = {}
if isinstance(data, dict):
for one in notice_map.keys():
result[one.lower()] = data.get(one, None)
else:
for one in notice_map.keys():
result[one.lower()] = env2str(one)
return result
================================================
FILE: dailycheckin/enshan/__init__.py
================================================
================================================
FILE: dailycheckin/enshan/main.py
================================================
import json
import os
import re
import requests
import urllib3
from dailycheckin import CheckIn
urllib3.disable_warnings()
class EnShan(CheckIn):
name = "恩山无线论坛"
def __init__(self, check_item):
self.check_item = check_item
@staticmethod
def get_formhash_from_page(session):
"""GET 签到页面并提取 formhash Discuz 常见的 CSRF 字段"""
response = session.get("https://www.right.com.cn/forum/forum.php", timeout=15)
response.raise_for_status()
html = response.text
# 常见两种位置:隐藏 input name="formhash" value="..." 或 js var formhash = '...'
m = re.search(r'name=["\']formhash["\']\s+value=["\']([0-9a-fA-F]+)["\']', html)
if not m:
m = re.search(r"formhash\s*[:=]\s*['\"]([0-9a-fA-F]+)['\"]", html)
if not m:
# 有时 formhash 包含非十六进制字符,放宽匹配
m = re.search(r'name=["\']formhash["\']\s+value=["\']([^"\']+)["\']', html)
if not m:
raise RuntimeError("无法在页面中找到 formhash,请检查页面或手动查看 HTML")
return m.group(1)
@staticmethod
def sign(session, form_hash):
msg = []
payload = {"formhash": form_hash}
response = session.post(
"https://www.right.com.cn/forum/plugin.php?id=erling_qd:action&action=sign", data=payload, timeout=15
)
try:
data = response.json()
if data.get("success"):
continuous_days = data.get("continuous_days")
msg = [
{
"name": "签到结果",
"value": data.get("message", "签到成功"),
},
{
"name": "连续签到",
"value": f"已连续签到{continuous_days}天",
},
]
else:
msg = [
{
"name": "签到结果",
"value": data.get("message", "签到失败"),
},
]
except ValueError:
msg = [
{
"name": "签到结果",
"value": f"签到异常:{response.status_code}",
}
]
# print(f'status_code: {response.status_code}, text: {response.text[:2000]}')
return msg
@staticmethod
def get_info(session):
msg = []
response = session.get("https://www.right.com.cn/FORUM/home.php?mod=spacecp&ac=credit&showcredit=1", timeout=15)
response.raise_for_status()
html = response.text
try:
coin = re.findall("恩山币: </em>(.*?) ", html)[0]
point = re.findall("<em>积分: </em>(.*?)<span", html)[0]
msg = [
{
"name": "恩山币",
"value": coin,
},
{
"name": "积分",
"value": point,
},
]
except Exception as e:
msg = [
{
"name": "获取代币失败",
"value": str(e),
}
]
return msg
def main(self):
cookie = self.check_item.get("cookie")
session = requests.Session()
session.headers.update(
{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
"Accept": "application/json, text/javascript, */*; q=0.01",
"Referer": "https://www.right.com.cn/forum/",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Cookie": cookie,
}
)
form_hash = self.get_formhash_from_page(session=session)
msg = self.sign(session=session, form_hash=form_hash)
msg += self.get_info(session=session)
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("ENSHAN", [])[0]
print(EnShan(check_item=_check_item).main())
================================================
FILE: dailycheckin/fnnasclub/__init__.py
================================================
================================================
FILE: dailycheckin/fnnasclub/main.py
================================================
import json
import os
import re
import requests
from dailycheckin import CheckIn
class FnNasClub(CheckIn):
name = "飞牛Nas论坛"
def __init__(self, check_item):
self.check_item = check_item
@staticmethod
def get_sign_param_from_page(session):
"""GET 签到页面并提取 sign"""
response = session.get("https://club.fnnas.com/plugin.php?id=zqlj_sign", timeout=15)
response.raise_for_status()
try:
html = response.text
# 匹配签到按钮,抓取sign参数
r_sign_btn = re.compile(r'<a href="plugin.php\?id=zqlj_sign&sign=([0-9a-fA-F]+)" class="btna">点击打卡</a>')
r_signed_btn = re.compile(
r'<a href="plugin.php\?id=zqlj_sign&sign=([0-9a-fA-F]+)" class="btna">今日已打卡</a>'
)
match = r_sign_btn.search(html)
match_signed = r_signed_btn.search(html)
sign_param = ""
if match:
# 匹配成功,取出sign参数
sign_param = match.group(1)
elif match_signed:
# 匹配成功,取出sign参数
sign_param = match_signed.group(1)
return sign_param
except Exception as e:
print(f"status_code: {response.status_code}, text: {response.text[:2000]}, exception: {e}")
return None
@staticmethod
def sign(session, sign_param):
if not sign_param:
msg = [
{
"name": "签到结果",
"value": "签到失败,未能成功获取sign参数",
}
]
return msg
response = session.get(f"https://club.fnnas.com/plugin.php?id=zqlj_sign&sign={sign_param}", timeout=15)
try:
html = response.text
# 匹配到 恭喜您,打卡成功! 证明打卡成功
if re.search(r"恭喜您,打卡成功!", html):
msg = [
{
"name": "签到结果",
"value": "签到成功",
}
]
elif re.search(r"您今天已经打过卡了,请勿重复操作!", html):
msg = [
{
"name": "签到结果",
"value": "您已签到,请勿重复签到",
}
]
else:
msg = [
{
"name": "签到结果",
"value": "未知签到异常",
}
]
except Exception as e:
msg = [
{
"name": "签到结果",
"value": f"签到异常,Exception: {e}, Status Code: {response.status_code}",
}
]
# print(f'status_code: {response.status_code}, text: {response.text[:2000]}')
return msg
@staticmethod
def get_info(session):
msg = []
response = session.get("https://club.fnnas.com/plugin.php?id=zqlj_sign", timeout=15)
response.raise_for_status()
try:
html = response.text
# 1. 匹配“我的打卡动态”这一整块 HTML
pattern = re.compile(
r"<strong>\s*我的打卡动态\s*</strong>" # strong 标题
r".*?" # 任意内容(非贪婪)
r'<div[^>]*class="bm_c"[^>]*>.*?</div>', # div.bm_c 完整区块
re.S,
)
m = pattern.search(html)
if not m:
raise RuntimeError("没匹配到 “我的打卡动态” 这一段 HTML")
block_html = m.group(0)
# 2. 保证每个 <li> 独立一行
block_html = re.sub(r"</li\s*>", "</li>\n", block_html)
# 3. 去掉所有 HTML 标签
text = re.sub(r"<[^>]+>", "", block_html)
# 4. 这里直接把“我的打卡动态”整个从文本里删除
text = text.replace("我的打卡动态", "")
# 5. 按行切分并清理空白
lines = [line.strip() for line in text.splitlines() if line.strip()]
# 6. 分割冒号并生成 msg 列表
for line in lines:
# 兼容全角“:”和半角“:”
if ":" in line:
sep = ":"
elif ":" in line:
sep = ":"
else:
continue
name, value = line.split(sep, 1)
msg.append(
{
"name": name.strip(),
"value": value.strip(),
}
)
except Exception as e:
msg = [
{
"name": "获取打卡动态失败",
"value": str(e),
}
]
return msg
def main(self):
cookie = self.check_item.get("cookie")
session = requests.Session()
session.headers.update(
{
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Referer": "https://club.fnnas.com/portal.php",
"Content-Type": "text/html; charset=utf-8",
"Cookie": cookie,
}
)
sign_param = self.get_sign_param_from_page(session=session)
msg = self.sign(session=session, sign_param=sign_param)
msg += self.get_info(session=session)
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("FNNASCLUB", [])[0]
print(FnNasClub(check_item=_check_item).main())
================================================
FILE: dailycheckin/imaotai/__init__.py
================================================
================================================
FILE: dailycheckin/imaotai/main.py
================================================
import base64
import datetime
import json
import math
import os
import random
import time
import requests
from Crypto.Cipher import AES
from dailycheckin import CheckIn
class Encrypt:
def __init__(self, key, iv):
self.key = key.encode("utf-8")
self.iv = iv.encode("utf-8")
def pkcs7padding(self, text):
"""明文使用PKCS7填充"""
bs = 16
length = len(text)
bytes_length = len(text.encode("utf-8"))
padding_size = length if (bytes_length == length) else bytes_length
padding = bs - padding_size % bs
padding_text = chr(padding) * padding
self.coding = chr(padding)
return text + padding_text
def aes_encrypt(self, content):
"""AES加密"""
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
content_padding = self.pkcs7padding(content)
encrypt_bytes = cipher.encrypt(content_padding.encode("utf-8"))
result = str(base64.b64encode(encrypt_bytes), encoding="utf-8")
return result
def aes_decrypt(self, content):
"""AES解密"""
cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
content = base64.b64decode(content)
text = cipher.decrypt(content).decode("utf-8")
return text.rstrip(self.coding)
class IMAOTAI(CheckIn):
name = "i茅台"
def __init__(self, check_item):
self.check_item = check_item
self.RESERVE_RULE = 0
self.mt_r = "clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/"
self.ITEM_MAP = {
"11318": "53%vol 500ml贵州茅台酒(乙巳蛇年)",
"11317": "53%vol 500ml贵州茅台酒(笙乐飞天)",
"11319": "53%vol 375mlx2贵州茅台酒(乙巳蛇年)",
"2478": "53%vol 500ml贵州茅台酒(珍品)",
"11240": "53%vol 500ml 茅台1935·中国国家地理文创酒(喜逢大运河)",
}
self.ITEM_CODES = ["11318", "11319"]
aes_key = "qbhajinldepmucsonaaaccgypwuvcjaa"
aes_iv = "2018534749963515"
self.encrypt = Encrypt(key=aes_key, iv=aes_iv)
self.mt_version = json.loads(requests.get("https://itunes.apple.com/cn/lookup?id=1600482450").text)["results"][
0
]["version"]
self.headers = {}
self.header_context = """
MT-Lat: 28.499562
MT-K: 1675213490331
MT-Lng: 102.182324
Host: app.moutai519.com.cn
MT-User-Tag: 0
Accept: */*
MT-Network-Type: WIFI
MT-Token: 1
MT-Info: 028e7f96f6369cafe1d105579c5b9377
MT-Device-ID: 2F2075D0-B66C-4287-A903-DBFF6358342A
MT-Bundle-ID: com.moutai.mall
Accept-Language: en-CN;q=1, zh-Hans-CN;q=0.9
MT-Request-ID: 167560018873318465
MT-APP-Version: 1.3.7
User-Agent: iOS;16.3;Apple;?unrecognized?
MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==
Content-Length: 93
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/json
userId: 2
"""
def init_headers(
self,
user_id: str = "1",
token: str = "2",
lat: str = "29.83826",
lng: str = "119.74375",
):
for k in self.header_context.strip().split("\n"):
temp_l = k.split(": ")
dict.update(self.headers, {temp_l[0]: temp_l[1]})
dict.update(self.headers, {"userId": user_id})
dict.update(self.headers, {"MT-Token": token})
dict.update(self.headers, {"MT-Lat": lat})
dict.update(self.headers, {"MT-Lng": lng})
dict.update(self.headers, {"MT-APP-Version": self.mt_version})
def get_current_session_id(self):
day_time = int(time.mktime(datetime.date.today().timetuple())) * 1000
my_url = f"https://static.moutai519.com.cn/mt-backend/xhr/front/mall/index/session/get/{day_time}"
responses = requests.get(my_url)
if responses.status_code != 200:
print(
f"get_current_session_id : params : {day_time}, response code : {responses.status_code}, response body : {responses.text}"
)
current_session_id = responses.json()["data"]["sessionId"]
dict.update(self.headers, {"current_session_id": str(current_session_id)})
def get_map(self, lat: str = "28.499562", lng: str = "102.182324"):
p_c_map = {}
url = "https://static.moutai519.com.cn/mt-backend/xhr/front/mall/resource/get"
headers = {
"X-Requested-With": "XMLHttpRequest",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_0_1 like Mac OS X)",
"Referer": "https://h5.moutai519.com.cn/gux/game/main?appConfig=2_1_2",
"Client-User-Agent": "iOS;16.0.1;Apple;iPhone 14 ProMax",
"MT-R": "clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==",
"Origin": "https://h5.moutai519.com.cn",
"MT-APP-Version": self.mt_version,
"MT-Request-ID": f"{int(time.time() * 1000)}{random.randint(1111111, 999999999)}{int(time.time() * 1000)}",
"Accept-Language": "zh-CN,zh-Hans;q=1",
"MT-Device-ID": f"{int(time.time() * 1000)}{random.randint(1111111, 999999999)}{int(time.time() * 1000)}",
"Accept": "application/json, text/javascript, */*; q=0.01",
"mt-lng": f"{lng}",
"mt-lat": f"{lat}",
}
res = requests.get(url, headers=headers)
mtshops = res.json().get("data", {}).get("mtshops_pc", {})
urls = mtshops.get("url")
r = requests.get(urls)
for k, v in dict(r.json()).items():
province_name = v.get("provinceName")
city_name = v.get("cityName")
if not p_c_map.get(province_name):
p_c_map[province_name] = {}
if not p_c_map[province_name].get(city_name, None):
p_c_map[province_name][city_name] = [k]
else:
p_c_map[province_name][city_name].append(k)
return p_c_map, dict(r.json())
def max_shop(self, city, item_code, p_c_map, province, shops):
max_count = 0
max_shop_id = "0"
shop_ids = p_c_map[province][city]
for shop in shops:
shop_id = shop["shopId"]
items = shop["items"]
if shop_id not in shop_ids:
continue
for item in items:
if item["itemId"] != str(item_code):
continue
if item["inventory"] > max_count:
max_count = item["inventory"]
max_shop_id = shop_id
print(f"item code {item_code}, max shop id : {max_shop_id}, max count : {max_count}")
return max_shop_id
def distance_shop(
self,
item_code,
shops,
source_data,
lat: str = "28.499562",
lng: str = "102.182324",
):
temp_list = []
for shop in shops:
shop_id = shop["shopId"]
items = shop["items"]
item_ids = [i["itemId"] for i in items]
if str(item_code) not in item_ids:
continue
shop_info = source_data.get(shop_id)
d = math.sqrt((float(lat) - shop_info["lat"]) ** 2 + (float(lng) - shop_info["lng"]) ** 2)
temp_list.append((d, shop_id))
temp_list = sorted(temp_list, key=lambda x: x[0])
if len(temp_list) > 0:
return temp_list[0][1]
else:
return "0"
def get_location_count(
self,
province: str,
city: str,
item_code: str,
p_c_map: dict,
source_data: dict,
lat: str = "29.83826",
lng: str = "102.182324",
reserve_rule: int = 0,
):
day_time = int(time.mktime(datetime.date.today().timetuple())) * 1000
session_id = self.headers["current_session_id"]
responses = requests.get(
f"https://static.moutai519.com.cn/mt-backend/xhr/front/mall/shop/list/slim/v3/{session_id}/{province}/{item_code}/{day_time}"
)
if responses.status_code != 200:
print(
f"get_location_count : params : {day_time}, response code : {responses.status_code}, response body : {responses.text}"
)
shops = responses.json()["data"]["shops"]
if reserve_rule == 0:
return self.distance_shop(item_code, shops, source_data, lat, lng)
if reserve_rule == 1:
return self.max_shop(city, item_code, p_c_map, province, shops)
def act_params(self, shop_id: str, item_id: str):
session_id = self.headers["current_session_id"]
user_id = self.headers["userId"]
params = {
"itemInfoList": [{"count": 1, "itemId": item_id}],
"sessionId": int(session_id),
"userId": user_id,
"shopId": shop_id,
}
s = json.dumps(params)
act = self.encrypt.aes_encrypt(s)
params.update({"actParam": act})
return params
def reservation(self, params: dict):
params.pop("userId")
responses = requests.post(
"https://app.moutai519.com.cn/xhr/front/mall/reservation/add",
json=params,
headers=self.headers,
).json()
if responses.get("code") == 401:
msg = {
"name": "申购结果",
"value": "token失效, 请重新抓包获取",
}
elif responses.get("code") != 2000:
msg = {
"name": "申购结果",
"value": responses.get("message"),
}
else:
msg = {
"name": "申购结果",
"value": responses.get("data", {}).get("successDesc"),
}
return msg
def getUserEnergyAward(self):
"""
耐力值
"""
cookies = {
"MT-Device-ID-Wap": self.headers["MT-Device-ID"],
"MT-Token-Wap": self.headers["MT-Token"],
"YX_SUPPORT_WEBP": "1",
}
response = requests.post(
url="https://h5.moutai519.com.cn/game/isolationPage/getUserEnergyAward",
cookies=cookies,
headers=self.headers,
json={},
).json()
if response.get("code") == 200:
msg = {
"name": "耐力",
"value": "✅领取耐力成功",
}
else:
msg = {
"name": "耐力",
"value": response.get("message"),
}
return msg
def main(self):
msg = []
mobile = self.check_item.get("mobile")
province = self.check_item.get("province")
city = self.check_item.get("city")
token = self.check_item.get("token")
user_id = self.check_item.get("userid")
lat = self.check_item.get("lat")
lng = self.check_item.get("lng")
item_codes = self.check_item.get("item_codes", self.ITEM_CODES)
reserve_rule = self.check_item.get("reserve_rule", 0)
msg = [
{
"name": "手机号",
"value": f"{mobile}",
},
{
"name": "省份城市",
"value": f"{province}{city}",
},
]
p_c_map, source_data = self.get_map(lat=lat, lng=lng)
self.get_current_session_id()
self.init_headers(user_id=user_id, token=token, lng=lng, lat=lat)
try:
for item in item_codes:
max_shop_id = self.get_location_count(
province=province,
city=city,
item_code=item,
p_c_map=p_c_map,
source_data=source_data,
lat=lat,
lng=lng,
reserve_rule=reserve_rule,
)
if max_shop_id == "0":
continue
reservation_params = self.act_params(max_shop_id, item)
reservation_msg = self.reservation(reservation_params)
time.sleep(20)
award_msg = self.getUserEnergyAward()
msg.append(reservation_msg)
msg.append(award_msg)
except BaseException as e:
msg.append(
{
"name": "申购结果",
"value": e,
}
)
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("IMAOTAI", [])[0]
print(IMAOTAI(check_item=_check_item).main())
================================================
FILE: dailycheckin/iqiyi/__init__.py
================================================
================================================
FILE: dailycheckin/iqiyi/main.py
================================================
import json
import os
import re
import time
from urllib.parse import unquote
from uuid import uuid4
import requests
from dailycheckin import CheckIn
class IQIYI(CheckIn):
name = "爱奇艺"
def __init__(self, check_item):
self.check_item = check_item
@staticmethod
def parse_cookie(cookie):
p00001 = re.findall(r"P00001=(.*?);", cookie)[0] if re.findall(r"P00001=(.*?);", cookie) else ""
p00002 = re.findall(r"P00002=(.*?);", cookie)[0] if re.findall(r"P00002=(.*?);", cookie) else ""
p00003 = re.findall(r"P00003=(.*?);", cookie)[0] if re.findall(r"P00003=(.*?);", cookie) else ""
__dfp = re.findall(r"__dfp=(.*?);", cookie)[0] if re.findall(r"__dfp=(.*?);", cookie) else ""
__dfp = __dfp.split("@")[0]
qyid = re.findall(r"QC005=(.*?);", cookie)[0] if re.findall(r"QC005=(.*?);", cookie) else ""
return p00001, p00002, p00003, __dfp, qyid
@staticmethod
def user_information(p00001):
"""
账号信息查询
"""
time.sleep(3)
url = "http://serv.vip.iqiyi.com/vipgrowth/query.action"
params = {"P00001": p00001}
res = requests.get(url=url, params=params).json()
if res["code"] == "A00000":
try:
res_data = res.get("data", {})
level = res_data.get("level", 0)
growthvalue = res_data.get("growthvalue", 0)
distance = res_data.get("distance", 0)
deadline = res_data.get("deadline", "非 VIP 用户")
today_growth_value = res_data.get("todayGrowthValue", 0)
msg = [
{"name": "VIP 等级", "value": level},
{"name": "当前成长", "value": growthvalue},
{"name": "今日成长", "value": today_growth_value},
{"name": "升级还需", "value": distance},
{"name": "VIP 到期", "value": deadline},
]
except Exception as e:
msg = [
{"name": "账号信息", "value": str(e)},
]
else:
msg = [
{"name": "账号信息", "value": res.get("msg")},
]
return msg
def lottery(self, p00001, award_list=[]):
url = "https://act.vip.iqiyi.com/shake-api/lottery"
params = {
"P00001": p00001,
"lotteryType": "0",
"actCode": "0k9GkUcjqqj4tne8",
}
params = {
"P00001": p00001,
"deviceID": str(uuid4()),
"version": "15.3.0",
"platform": str(uuid4())[:16],
"lotteryType": "0",
"actCode": "0k9GkUcjqqj4tne8",
"extendParams": json.dumps(
{
"appIds": "iqiyi_pt_vip_iphone_video_autorenew_12m_348yuan_v2",
"supportSk2Identity": True,
"testMode": "0",
"iosSystemVersion": "17.4",
"bundleId": "com.qiyi.iphone",
}
),
}
res = requests.get(url, params=params).json()
msgs = []
if res.get("code") == "A00000":
award_info = res.get("data", {}).get("title")
award_list.append(award_info)
time.sleep(3)
return self.lottery(p00001=p00001, award_list=award_list)
elif res.get("msg") == "抽奖次数用完":
if award_list:
msgs = [{"name": "每天摇一摇", "value": "、".join(award_list)}]
else:
msgs = [{"name": "每天摇一摇", "value": res.get("msg")}]
else:
msgs = [{"name": "每天摇一摇", "value": res.get("msg")}]
return msgs
@staticmethod
def draw(draw_type, p00001, p00003):
"""
查询抽奖次数(必),抽奖
:param draw_type: 类型 0 查询次数 1 抽奖
:param p00001: 关键参数
:param p00003: 关键参数
:return: {status, msg, chance}
"""
url = "https://iface2.iqiyi.com/aggregate/3.0/lottery_activity"
params = {
"lottery_chance": 1,
"app_k": "b398b8ccbaeacca840073a7ee9b7e7e6",
"app_v": "11.6.5",
"platform_id": 10,
"dev_os": "8.0.0",
"dev_ua": "FRD-AL10",
"net_sts": 1,
"qyid": "2655b332a116d2247fac3dd66a5285011102",
"psp_uid": p00003,
"psp_cki": p00001,
"psp_status": 3,
"secure_v": 1,
"secure_p": "GPhone",
"req_sn": round(time.time() * 1000),
}
if draw_type == 1:
del params["lottery_chance"]
res = requests.get(url=url, params=params).json()
if not res.get("code"):
chance = int(res.get("daysurpluschance"))
msg = res.get("awardName")
return {"status": True, "msg": msg, "chance": chance}
else:
try:
msg = res.get("kv", {}).get("msg")
except Exception as e:
print(e)
msg = res["errorReason"]
return {"status": False, "msg": msg, "chance": 0}
def level_right(self, p00001):
data = {"code": "k8sj74234c683f", "P00001": p00001}
res = requests.post(url="https://act.vip.iqiyi.com/level-right/receive", data=data).json()
msg = res["msg"]
return [{"name": "V7 免费升级星钻", "value": msg}]
def give_times(self, p00001):
url = "https://pcell.iqiyi.com/lotto/giveTimes"
times_code_list = ["browseWeb", "browseWeb", "bookingMovie"]
for times_code in times_code_list:
params = {
"actCode": "bcf9d354bc9f677c",
"timesCode": times_code,
"P00001": p00001,
}
requests.get(url, params=params)
def lotto_lottery(self, p00001):
self.give_times(p00001=p00001)
gift_list = []
for _ in range(5):
url = "https://pcell.iqiyi.com/lotto/lottery"
params = {"actCode": "bcf9d354bc9f677c", "P00001": p00001}
response = requests.get(url, params=params)
gift_name = response.json()["data"]["giftName"]
if gift_name and "未中奖" not in gift_name:
gift_list.append(gift_name)
if gift_list:
return [{"name": "白金抽奖", "value": "、".join(gift_list)}]
else:
return [{"name": "白金抽奖", "value": "未中奖"}]
def main(self):
p00001, p00002, p00003, dfp, qyid = self.parse_cookie(self.check_item.get("cookie"))
try:
user_info = json.loads(unquote(p00002, encoding="utf-8"))
user_name = user_info.get("user_name")
user_name = user_name.replace(user_name[3:7], "****")
nickname = user_info.get("nickname")
except Exception as e:
print(f"获取账号信息失败,错误信息: {e}")
nickname = "未获取到,请检查 Cookie 中 P00002 字段"
user_name = "未获取到,请检查 Cookie 中 P00002 字段"
_user_msg = self.user_information(p00001=p00001)
lotto_lottery_msg = self.lotto_lottery(p00001=p00001)
if _user_msg[4].get("value") != "非 VIP 用户":
level_right_msg = self.level_right(p00001=p00001)
else:
level_right_msg = [
{
"name": "V7 免费升级星钻",
"value": "非 VIP 用户",
}
]
chance = self.draw(draw_type=0, p00001=p00001, p00003=p00003)["chance"]
lottery_msgs = self.lottery(p00001=p00001, award_list=[])
if chance:
draw_msg = ""
for _ in range(chance):
ret = self.draw(draw_type=1, p00001=p00001, p00003=p00003)
draw_msg += ret["msg"] + ";" if ret["status"] else ""
else:
draw_msg = "抽奖机会不足"
user_msg = self.user_information(p00001=p00001)
msg = [
{"name": "用户账号", "value": user_name},
{"name": "用户昵称", "value": nickname},
*user_msg,
{"name": "抽奖奖励", "value": draw_msg},
*lottery_msgs,
*level_right_msg,
*lotto_lottery_msg,
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("IQIYI", [])[0]
print(IQIYI(check_item=_check_item).main())
================================================
FILE: dailycheckin/kgqq/__init__.py
================================================
================================================
FILE: dailycheckin/kgqq/main.py
================================================
import json
import os
import requests
from dailycheckin import CheckIn
class KGQQ(CheckIn):
name = "全民K歌"
def __init__(self, check_item):
self.check_item = check_item
@staticmethod
def sign(kgqq_cookie):
headers = {"Cookie": kgqq_cookie}
uid = kgqq_cookie.split("; ")
t_uuid = ""
for i in uid:
if i.find("uid=") >= 0:
t_uuid = i.split("=")[1]
proto_profile_url = f"https://node.kg.qq.com/webapp/proxy?ns=proto_profile&cmd=profile.getProfile&mapExt=JTdCJTIyZmlsZSUyMiUzQSUyMnByb2ZpbGVfd2ViYXBwSmNlJTIyJTJDJTIyY21kTmFtZSUyMiUzQSUyMlByb2ZpbGVHZXQlMjIlMkMlMjJhcHBpZCUyMiUzQTEwMDA2MjYlMkMlMjJkY2FwaSUyMiUzQSU3QiUyMmludGVyZmFjZUlkJTIyJTNBMjA1MzU5NTk3JTdEJTJDJTIybDVhcGklMjIlM0ElN0IlMjJtb2RpZCUyMiUzQTI5NDAxNyUyQyUyMmNtZCUyMiUzQTI2MjE0NCU3RCUyQyUyMmlwJTIyJTNBJTIyMTAwLjExMy4xNjIuMTc4JTIyJTJDJTIycG9ydCUyMiUzQSUyMjEyNDA2JTIyJTdE&t_uUid={t_uuid}"
url_list = (
[
f"https://node.kg.qq.com/webapp/proxy?ns=KG_TASK&cmd=task.getLottery&ns_inbuf=&mapExt=JTdCJTIyZmlsZSUyMiUzQSUyMnRhc2tKY2UlMjIlMkMlMjJjbWROYW1lJTIyJTNBJTIyTG90dGVyeVJlcSUyMiUyQyUyMnduc0NvbmZpZyUyMiUzQSU3QiUyMmFwcGlkJTIyJTNBMTAwMDU1NyU3RCUyQyUyMmw1YXBpJTIyJTNBJTdCJTIybW9kaWQlMjIlM0E1MDM5MzclMkMlMjJjbWQlMjIlM0E1ODk4MjQlN0QlN0Q%3D&t_uid={t_uuid}&t_iShowEntry=1&t_type={one}"
for one in ["1", "2"]
]
+ [
f"https://node.kg.qq.com/webapp/proxy?ns=KG_TASK&cmd=task.signinGetAward&mapExt=JTdCJTIyZmlsZSUyMiUzQSUyMnRhc2tKY2UlMjIlMkMlMjJjbWROYW1lJTIyJTNBJTIyR2V0U2lnbkluQXdhcmRSZXElMjIlMkMlMjJ3bnNDb25maWclMjIlM0ElN0IlMjJhcHBpZCUyMiUzQTEwMDA2MjYlN0QlMkMlMjJsNWFwaSUyMiUzQSU3QiUyMm1vZGlkJTIyJTNBNTAzOTM3JTJDJTIyY21kJTIyJTNBNTg5ODI0JTdEJTdE&t_uid={t_uuid}&t_iShowEntry={one}"
for one in ["1", "2", "4", "16", "128", "512"]
]
+ [
f"https://node.kg.qq.com/webapp/proxy?ns=KG_TASK&cmd=task.getLottery&mapExt=JTdCJTIyZmlsZSUyMiUzQSUyMnRhc2tKY2UlMjIlMkMlMjJjbWROYW1lJTIyJTNBJTIyTG90dGVyeVJlcSUyMiUyQyUyMnduc0NvbmZpZyUyMiUzQSU3QiUyMmFwcGlkJTIyJTNBMTAwMDU1NyU3RCUyQyUyMmw1YXBpJTIyJTNBJTdCJTIybW9kaWQlMjIlM0E1MDM5MzclMkMlMjJjbWQlMjIlM0E1ODk4MjQlN0QlN0Q&t_uid={t_uuid}&t_iShowEntry=4&t_type=104",
f"https://node.kg.qq.com/webapp/proxy?ns=KG_TASK&cmd=task.getLottery&mapExt=JTdCJTIyZmlsZSUyMiUzQSUyMnRhc2tKY2UlMjIlMkMlMjJjbWROYW1lJTIyJTNBJTIyTG90dGVyeVJlcSUyMiUyQyUyMmw1YXBpJTIyJTNBJTdCJTIybW9kaWQlMjIlM0E1MDM5MzclMkMlMjJjbWQlMjIlM0E1ODk4MjQlN0QlMkMlMjJsNWFwaV9leHAxJTIyJTNBJTdCJTIybW9kaWQlMjIlM0E4MTcwODklMkMlMjJjbWQlMjIlM0EzODAxMDg4JTdEJTdE&t_uid={t_uuid}&t_type=103",
]
)
proto_music_station_url = f"https://node.kg.qq.com/webapp/proxy?ns=proto_music_station&cmd=message.batch_get_music_cards&mapExt=JTdCJTIyY21kTmFtZSUyMiUzQSUyMkdldEJhdGNoTXVzaWNDYXJkc1JlcSUyMiUyQyUyMmZpbGUlMjIlM0ElMjJwcm90b19tdXNpY19zdGF0aW9uSmNlJTIyJTJDJTIyd25zRGlzcGF0Y2hlciUyMiUzQXRydWUlN0Q&t_uUid={t_uuid}&g_tk_openkey="
url_10 = f"https://node.kg.qq.com/webapp/proxy?t_stReward%3Aobject=%7B%22uInteractiveType%22%3A1%2C%22uRewardType%22%3A0%2C%22uFlowerNum%22%3A15%7D&ns=proto_music_station&cmd=message.get_reward&mapExt=JTdCJTIyY21kTmFtZSUyMiUzQSUyMkdldFJld2FyZFJlcSUyMiUyQyUyMmZpbGUlMjIlM0ElMjJwcm90b19tdXNpY19zdGF0aW9uSmNlJTIyJTJDJTIyd25zRGlzcGF0Y2hlciUyMiUzQXRydWUlN0Q&t_uUid={t_uuid}&t_strUgcId="
url_15 = f"https://node.kg.qq.com/webapp/proxy?t_stReward%3Aobject=%7B%22uInteractiveType%22%3A0%2C%22uRewardType%22%3A0%2C%22uFlowerNum%22%3A10%7D&ns=proto_music_station&cmd=message.get_reward&mapExt=JTdCJTIyY21kTmFtZSUyMiUzQSUyMkdldFJld2FyZFJlcSUyMiUyQyUyMmZpbGUlMjIlM0ElMjJwcm90b19tdXNpY19zdGF0aW9uSmNlJTIyJTJDJTIyd25zRGlzcGF0Y2hlciUyMiUzQXRydWUlN0Q&t_uUid={t_uuid}&t_strUgcId="
try:
old_proto_profile_response = requests.get(url=proto_profile_url, headers=headers)
old_num = old_proto_profile_response.json()["data"]["profile.getProfile"]["uFlowerNum"]
nickname = old_proto_profile_response.json()["data"]["profile.getProfile"]["stPersonInfo"]["sKgNick"]
for url in url_list:
try:
requests.get(url=url, headers=headers)
except Exception as e:
print(e)
for g_tk_openkey in range(16):
try:
proto_music_station_resp = requests.get(
url=proto_music_station_url + str(g_tk_openkey), headers=headers
)
if proto_music_station_resp.json().get("code") in [1000]:
return proto_music_station_resp.json().get("msg")
vct_music_cards = proto_music_station_resp.json()["data"]["message.batch_get_music_cards"][
"vctMusicCards"
]
vct_music_cards_list = sorted(
vct_music_cards,
key=lambda x: x["stReward"]["uFlowerNum"],
reverse=True,
)[0]
str_ugc_id = vct_music_cards_list["strUgcId"]
str_key = vct_music_cards_list["strKey"]
url = str_ugc_id + "&t_strKey=" + str_key
u_flower_num = vct_music_cards_list["stReward"]["uFlowerNum"]
if u_flower_num > 10:
requests.get(url=url_10 + url, headers=headers)
elif 1 < u_flower_num < 10:
requests.get(url=url_15 + url, headers=headers)
except Exception as e:
print(e)
# VIP 签到
try:
getinfourl = (
"https://node.kg.qq.com/webapp/proxy?ns=proto_vip_webapp&cmd=vip.get_vip_info&t_uUid="
+ t_uuid
+ "&t_uWebReq=1&t_uGetDataFromC4B=1"
)
inforequest = requests.get(url=getinfourl, headers=headers)
vip_status = inforequest.json()["data"]["vip.get_vip_info"]["stVipCoreInfo"]["uStatus"]
if vip_status == 1:
vipurl = (
"https://node.kg.qq.com/webapp/proxy?t_uUid="
+ t_uuid
+ "&ns=proto_vip_webapp&cmd=vip.get_vip_day_reward&ns_inbuf=&nocache=1613719349184&mapExt=JTdCJTIyY21kTmFtZSUyMiUzQSUyMkdldFZpcERheVJld2FyZCUyMiU3RA%3D%3D&g_tk_openkey=642424811"
)
viprequest = requests.get(url=vipurl, headers=headers)
str_tips = viprequest.json()["data"]["vip.get_vip_day_reward"]["strTips"]
u_cur_reward_num = viprequest.json()["data"]["vip.get_vip_day_reward"]["uCurRewardNum"]
vip_message = f"{str_tips} 获取VIP福利道具:{u_cur_reward_num}个"
else:
vip_message = "非 VIP 用户"
except Exception as e:
print(e)
vip_message = "VIP 签到失败"
new_proto_profile_response = requests.get(url=proto_profile_url, headers=headers)
new_num = new_proto_profile_response.json()["data"]["profile.getProfile"]["uFlowerNum"]
get_num = int(new_num) - int(old_num)
msg = [
{"name": "帐号信息", "value": nickname},
{"name": "获取鲜花", "value": get_num},
{"name": "当前鲜花", "value": new_num},
{"name": "VIP 签到", "value": vip_message},
]
except Exception as e:
msg = [
{"name": "帐号信息", "value": str(e)},
]
return msg
def main(self):
kgqq_cookie = self.check_item.get("cookie")
msg = self.sign(kgqq_cookie=kgqq_cookie)
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("KGQQ", [])[0]
print(KGQQ(check_item=_check_item).main())
================================================
FILE: dailycheckin/main.py
================================================
import argparse
import json
import os
import time
from datetime import datetime, timedelta
import requests
from dailycheckin.__version__ import __version__
from dailycheckin.configs import checkin_map, get_checkin_info, get_notice_info
from dailycheckin.utils.message import push_message
def parse_arguments():
parser = argparse.ArgumentParser()
parser.add_argument("--include", nargs="+", help="任务执行包含的任务列表")
parser.add_argument("--exclude", nargs="+", help="任务执行排除的任务列表")
return parser.parse_args()
def check_config(task_list):
config_path = None
config_path_list = []
for one_path in [
"/ql/scripts/config.json",
"config.json",
"../config.json",
"./config/config.json",
"../config/config.json",
"/config.json",
]:
_config_path = os.path.join(os.getcwd(), one_path)
if os.path.exists(_config_path):
config_path = os.path.normpath(_config_path)
break
config_path_list.append(os.path.normpath(os.path.dirname(_config_path)))
if config_path:
print("使用配置文件路径:", config_path)
with open(config_path, encoding="utf-8") as f:
try:
data = json.load(f)
except Exception:
print("Json 格式错误,请检查 config.json 文件格式是否正确!")
return False, False
try:
notice_info = get_notice_info(data=data)
_check_info = get_checkin_info(data=data)
check_info = {}
for one_check in checkin_map.keys():
if one_check in task_list:
if _check_info.get(one_check.lower()):
for _, check_item in enumerate(_check_info.get(one_check.lower(), [])):
if "xxxxxx" not in str(check_item) and "多账号" not in str(check_item):
if one_check.lower() not in check_info.keys():
check_info[one_check.lower()] = []
check_info[one_check.lower()].append(check_item)
return notice_info, check_info
except Exception as e:
print(e)
return False, False
else:
print("未找到 config.json 配置文件\n请在下方任意目录中添加「config.json」文件:\n" + "\n".join(config_path_list))
return False, False
def checkin():
start_time = time.time()
utc_time = (datetime.utcnow() + timedelta(hours=8)).strftime("%Y-%m-%d %H:%M:%S")
print(f"当前时间: {utc_time}\n当前版本: {__version__}")
args = parse_arguments()
include = args.include
exclude = args.exclude
if not include:
include = list(checkin_map.keys())
else:
include = [one for one in include if one in checkin_map.keys()]
if not exclude:
exclude = []
else:
exclude = [one for one in exclude if one in checkin_map.keys()]
task_list = list(set(include) - set(exclude))
notice_info, check_info = check_config(task_list)
if check_info:
task_name_str = "\n".join(
[f"「{checkin_map.get(one.upper())[0]}」账号数 : {len(value)}" for one, value in check_info.items()]
)
print(f"\n---------- 本次执行签到任务如下 ----------\n\n{task_name_str}\n\n")
content_list = []
for one_check, check_list in check_info.items():
check_name, check_func = checkin_map.get(one_check.upper())
print(f"----------开始执行「{check_name}」签到----------")
for index, check_item in enumerate(check_list):
try:
msg = check_func(check_item).main()
content_list.append(f"「{check_name}」\n{msg}")
print(f"第 {index + 1} 个账号: ✅✅✅✅✅")
except Exception as e:
content_list.append(f"「{check_name}」\n{e}")
print(f"第 {index + 1} 个账号: ❌❌❌❌❌\n{e}")
print("\n\n")
try:
url = "https://pypi.org/pypi/dailycheckin/json"
latest_version = requests.get(url=url, timeout=30).json()["info"]["version"]
except Exception:
print("获取最新版本失败")
latest_version = "0.0.0"
content_list.append(
f"开始时间: {utc_time}\n"
f"任务用时: {int(time.time() - start_time)} 秒\n"
f"当前版本: {__version__}\n"
f"最新版本: {latest_version}\n"
f"项目地址: https://github.com/Sitoi/dailycheckin"
)
push_message(content_list=content_list, notice_info=notice_info)
return
if __name__ == "__main__":
checkin()
================================================
FILE: dailycheckin/mimotion/__init__.py
================================================
================================================
FILE: dailycheckin/mimotion/main.py
================================================
import json
import os
import random
import re
import time
import requests
from dailycheckin import CheckIn
class MiMotion(CheckIn):
name = "小米运动"
def __init__(self, check_item):
self.check_item = check_item
self.headers = {
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"User-Agent": "MiFit/6.12.0 (MCE16; Android 16; Density/1.5)",
"app_name": "com.xiaomi.hm.health",
}
def get_time(self):
try:
url = "https://acs.m.taobao.com/gw/mtop.common.getTimestamp/"
response = requests.get(url, headers=self.headers).json()
t = response["data"]["t"]
return t
except Exception as e:
print("时间戳获取失败,使用本地时间", e)
return str(int(time.time() * 1000))
def login(self, phone, password):
phone_pattern = r"(^(1)\d{10}$)"
if re.match(phone_pattern, phone):
user = f"+86{phone}"
third_name = "huami_phone"
else:
user = phone
third_name = "huami"
url1 = "https://api-user.zepp.com/registrations/" + user + "/tokens"
data1 = f"client_id=HuaMi&country_code=CN&json_response=true&name={user}&password={password}&redirect_uri=https://s3-us-west-2.amazonaws.com/hm-registration/successsignin.html&state=REDIRECTION&token=access"
try:
r1 = requests.post(url1, data=data1, headers=self.headers)
if r1.status_code == 429:
return 0, 0, "请求过于频繁,请变换IP后再试"
r1 = r1.json()
code = r1["access"]
except Exception as e:
print("登录失败:", e)
return 0, 0, "登录失败"
url2 = "https://account.zepp.com/v2/client/login"
data2 = f"app_name=com.xiaomi.hm.health&country_code=CN&code={code}&device_id=fuck1069-2002-7869-0129-757geoi6sam1&device_model=android_phone&app_version=6.12.0&grant_type=access_token&allow_registration=false&dn=account.zepp.com,api-user.zepp.com,api-mifit.zepp.com,api-watch.zepp.com,app-analytics.zepp.com,api-analytics.huami.com,auth.zepp.com&source=com.xiaomi.hm.health&third_name={third_name}"
try:
r2 = requests.post(url=url2, data=data2, headers=self.headers).json()
login_token = r2["token_info"]["login_token"]
userid = r2["token_info"]["user_id"]
app_token = r2["token_info"]["app_token"]
return login_token, userid, app_token
except Exception as e:
print("获取token失败:", e)
return 0, 0, "获取token失败"
def main(self):
phone = str(self.check_item.get("phone"))
password = str(self.check_item.get("password"))
try:
min_step = int(self.check_item.get("min_step", 10000))
except Exception as e:
print("初始化步数失败: 已将最小值设置为 10000", e)
min_step = 10000
try:
max_step = int(self.check_item.get("max_step", 19999))
except Exception as e:
print("初始化步数失败: 已将最大值设置为 19999", e)
max_step = 19999
step = str(random.randint(min_step, max_step))
login_token, userid, app_token = self.login(phone, password)
if login_token == 0:
msg = [
{"name": "帐号信息", "value": f"{phone[:4]}****{phone[-4:]}"},
{"name": "修改信息", "value": "登陆失败"},
]
else:
t = self.get_time()
today = time.strftime("%F")
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%222025-08-17%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%3A1755407692%2C%5C%22ed%5C%22%3A1755407692%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%3A17760%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"
finddate = re.compile(r".*?date%22%3A%22(.*?)%22%2C%22data.*?")
findstep = re.compile(r".*?ttl%5C%22%3A(.*?)%2C%5C%22dis.*?")
data_json = re.sub(finddate.findall(data_json)[0], today, str(data_json))
data_json = re.sub(findstep.findall(data_json)[0], step, str(data_json))
url = f"https://api-mifit-cn.huami.com/v1/data/band_data.json?&t={t}"
headers = {
"apptoken": app_token,
"Content-Type": "application/x-www-form-urlencoded",
}
data = f"userid={userid}&last_sync_data_time=1628256960&device_type=0&last_deviceid=C4BDB6FFFE2BCA4C&data_json={data_json}"
response = requests.post(url=url, data=data, headers=headers).json()
msg = [
{"name": "帐号信息", "value": f"{phone[:4]}****{phone[-4:]}"},
{"name": "修改信息", "value": f"{response['message']}"},
{"name": "修改步数", "value": f"{step}"},
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("MIMOTION", [])[0]
print(MiMotion(check_item=_check_item).main())
================================================
FILE: dailycheckin/smzdm/__init__.py
================================================
================================================
FILE: dailycheckin/smzdm/main.py
================================================
import hashlib
import json
import os
import re
import time
import requests
import urllib3
from dailycheckin import CheckIn
urllib3.disable_warnings()
class SMZDM(CheckIn):
name = "什么值得买"
def __init__(self, check_item: dict):
self.check_item = check_item
def robot_token(self, headers):
ts = round(time.time() * 1000)
url = "https://user-api.smzdm.com/robot/token"
data = {
"f": "android",
"v": "10.4.1",
"weixin": 1,
"time": ts,
"sign": hashlib.md5(
bytes(
f"f=android&time={ts}&v=10.4.1&weixin=1&key=apr1$AwP!wRRT$gJ/q.X24poeBInlUJC",
encoding="utf-8",
)
)
.hexdigest()
.upper(),
}
html = requests.post(url=url, headers=headers, data=data)
result = html.json()
token = result["data"]["token"]
return token
def sign(self, headers, token):
time_stamp = round(time.time() * 1000)
data = {
"f": "android",
"v": "10.4.1",
"sk": "ierkM0OZZbsuBKLoAgQ6OJneLMXBQXmzX+LXkNTuKch8Ui2jGlahuFyWIzBiDq/L",
"weixin": 1,
"time": time_stamp,
"token": token,
"sign": hashlib.md5(
bytes(
f"f=android&sk=ierkM0OZZbsuBKLoAgQ6OJneLMXBQXmzX+LXkNTuKch8Ui2jGlahuFyWIzBiDq/L&time={time_stamp}&token={token}&v=10.4.1&weixin=1&key=apr1$AwP!wRRT$gJ/q.X24poeBInlUJC",
encoding="utf-8",
)
)
.hexdigest()
.upper(),
}
url = "https://user-api.smzdm.com/checkin"
resp = requests.post(url=url, headers=headers, data=data)
error_msg = resp.json()["error_msg"]
return error_msg, data
def all_reward(self, headers, data):
url2 = "https://user-api.smzdm.com/checkin/all_reward"
resp = requests.post(url=url2, headers=headers, data=data)
result = resp.json()
msgs = []
if normal_reward := result["data"]["normal_reward"]:
try:
msgs = [
{
"name": "签到奖励",
"value": normal_reward["reward_add"]["content"],
},
{
"name": "连续签到",
"value": normal_reward["sub_title"],
},
]
except Exception as e:
print(e)
return msgs
def active(self, cookie):
zdm_active_id = ["ljX8qVlEA7"]
for active_id in zdm_active_id:
url = f"https://zhiyou.smzdm.com/user/lottery/jsonp_draw?active_id={active_id}"
rewardurl = f"https://zhiyou.smzdm.com/user/lottery/jsonp_get_active_info?active_id={active_id}"
infourl = "https://zhiyou.smzdm.com/user/"
headers = {
"Host": "zhiyou.smzdm.com",
"Accept": "*/*",
"Connection": "keep-alive",
"Cookie": cookie,
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148/smzdm 10.4.6 rv:130.1 (iPhone 13; iOS 15.6; zh_CN)/iphone_smzdmapp/10.4.6/wkwebview/jsbv_1.0.0",
"Accept-Language": "zh-CN,zh-Hans;q=0.9",
"Referer": "https://m.smzdm.com/",
"Accept-Encoding": "gzip, deflate, br",
}
response = requests.post(url=url, headers=headers).json()
response_info = requests.get(url=infourl, headers=headers).text
_ = requests.get(url=rewardurl, headers=headers).json()
name = (
str(
re.findall(
'<a href="https://zhiyou.smzdm.com/user"> (.*?) </a>',
str(response_info),
re.S,
)
)
.replace("[", "")
.replace("]", "")
.replace("'", "")
)
level = (
str(
re.findall(
r'<img src="https://res.smzdm.com/h5/h5_user/dist/assets/level/(.*?).png\?v=1">',
str(response_info),
re.S,
)
)
.replace("[", "")
.replace("]", "")
.replace("'", "")
)
gold = (
str(
re.findall(
'<div class="assets-part assets-gold">\n (.*?)</span>',
str(response_info),
re.S,
)
)
.replace("[", "")
.replace("]", "")
.replace("'’", "")
.replace('<span class="assets-part-element assets-num">', "")
.replace("'", "")
)
silver = (
str(
re.findall(
'<div class="assets-part assets-prestige">\n (.*?)</span>',
str(response_info),
re.S,
)
)
.replace("[", "")
.replace("]", "")
.replace("'’", "")
.replace('<span class="assets-part-element assets-num">', "")
.replace("'", "")
)
msg = [
{
"name": "签到结果",
"value": response["error_msg"],
},
{"name": "等级", "value": level},
{"name": "昵称", "value": name},
{"name": "金币", "value": gold},
{"name": "碎银", "value": silver},
]
return msg
def main(self):
cookie = self.check_item.get("cookie")
headers = {
"Host": "user-api.smzdm.com",
"Content-Type": "application/x-www-form-urlencoded",
"Cookie": cookie,
"User-Agent": "smzdm_android_V10.4.1 rv:841 (22021211RC;Android12;zh)smzdmapp",
}
msg = self.active(cookie)
token = self.robot_token(headers)
error_msg, data = self.sign(headers, token)
msg.append({"name": "签到结果", "value": error_msg})
reward_msg = self.all_reward(headers, data)
msg += reward_msg
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("SMZDM", [])[0]
print(SMZDM(check_item=_check_item).main())
================================================
FILE: dailycheckin/tieba/__init__.py
================================================
================================================
FILE: dailycheckin/tieba/main.py
================================================
import hashlib
import json
import os
import random
import time
from typing import Optional
import requests
from dailycheckin import CheckIn
class Tieba(CheckIn):
name = "百度贴吧"
def __init__(self, check_item: dict):
self.TBS_URL = "http://tieba.baidu.com/dc/common/tbs"
self.LIKE_URL = "http://c.tieba.baidu.com/c/f/forum/like"
self.SIGN_URL = "http://c.tieba.baidu.com/c/c/forum/sign"
self.LOGIN_INFO_URL = "https://zhidao.baidu.com/api/loginInfo"
self.SIGN_KEY = "tiebaclient!!!"
self.HEADERS = {
"Host": "tieba.baidu.com",
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36",
"Connection": "keep-alive",
"Accept-Encoding": "gzip, deflate",
"Cache-Control": "no-cache",
}
self.SIGN_DATA = {
"_client_type": "2",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"model": "MI+5",
"net_type": "1",
}
self.session = requests.Session()
self.session.headers.update(self.HEADERS)
cookie = check_item.get("cookie")
if not cookie:
raise ValueError("必须提供 BDUSS 或完整 Cookie")
cookie_dict = {item.split("=")[0]: item.split("=")[1] for item in cookie.split("; ") if "=" in item}
requests.utils.add_dict_to_cookiejar(self.session.cookies, cookie_dict)
self.bduss = cookie_dict.get("BDUSS", "")
if not self.bduss:
raise ValueError("Cookie 中未找到 BDUSS")
def request(self, url: str, method: str = "get", data: Optional[dict] = None, retry: int = 3) -> dict:
for i in range(retry):
try:
if method.lower() == "get":
response = self.session.get(url, timeout=10)
else:
response = self.session.post(url, data=data, timeout=10)
response.raise_for_status()
if not response.text.strip():
raise ValueError("空响应内容")
return response.json()
except Exception as e:
if i == retry - 1:
raise Exception(f"请求失败: {e!s}")
wait_time = 1.5 * (2**i) + random.uniform(0, 1)
time.sleep(wait_time)
raise Exception(f"请求失败,已达最大重试次数 {retry}")
def encode_data(self, data: dict) -> dict:
s = ""
for key in sorted(data.keys()):
s += f"{key}={data[key]}"
sign = hashlib.md5((s + self.SIGN_KEY).encode("utf-8")).hexdigest().upper()
data.update({"sign": sign})
return data
def get_user_info(self):
try:
result = self.request(self.TBS_URL)
if result.get("is_login", 0) == 0:
return False, "登录失败,Cookie 异常"
tbs = result.get("tbs", "")
try:
user_info = self.request(self.LOGIN_INFO_URL)
user_name = user_info.get("userName", "未知用户")
except Exception:
user_name = "未知用户"
return tbs, user_name
except Exception as e:
return False, f"登录验证异常: {e}"
def get_favorite(self) -> list[dict]:
forums = []
page_no = 1
while True:
data = {
"BDUSS": self.bduss,
"_client_type": "2",
"_client_id": "wappc_1534235498291_488",
"_client_version": "9.7.8.0",
"_phone_imei": "000000000000000",
"from": "1008621y",
"page_no": str(page_no),
"page_size": "200",
"model": "MI+5",
"net_type": "1",
"timestamp": str(int(time.time())),
"vcode_tag": "11",
}
data = self.encode_data(data)
try:
res = self.request(self.LIKE_URL, "post", data)
if "forum_list" in res:
for forum_type in ["non-gconforum", "gconforum"]:
if forum_type in res["forum_list"]:
items = res["forum_list"][forum_type]
if isinstance(items, list):
forums.extend(items)
elif isinstance(items, dict):
forums.append(items)
if res.get("has_more") != "1":
break
page_no += 1
time.sleep(random.uniform(1, 2))
except Exception as e:
print(f"获取贴吧列表出错: {e}")
break
print(f"共获取到 {len(forums)} 个关注的贴吧")
return forums
def sign_forums(self, forums, tbs: str) -> dict:
success_count, error_count, exist_count, shield_count = 0, 0, 0, 0
total = len(forums)
print(f"开始签到 {total} 个贴吧")
last_request_time = time.time()
for idx, forum in enumerate(forums):
elapsed = time.time() - last_request_time
delay = max(0, 1.0 + random.uniform(0.5, 1.5) - elapsed)
time.sleep(delay)
last_request_time = time.time()
if (idx + 1) % 10 == 0:
extra_delay = random.uniform(5, 10)
print(f"已签到 {idx + 1}/{total} 个贴吧,休息 {extra_delay:.2f} 秒")
time.sleep(extra_delay)
forum_name = forum.get("name", "")
forum_id = forum.get("id", "")
log_prefix = f"【{forum_name}】吧({idx + 1}/{total})"
try:
data = self.SIGN_DATA.copy()
data.update(
{
"BDUSS": self.bduss,
"fid": forum_id,
"kw": forum_name,
"tbs": tbs,
"timestamp": str(int(time.time())),
}
)
data = self.encode_data(data)
result = self.request(self.SIGN_URL, "post", data)
error_code = result.get("error_code", "")
if error_code == "0":
success_count += 1
if "user_info" in result:
rank = result["user_info"]["user_sign_rank"]
print(f"{log_prefix} 签到成功,第{rank}个签到")
else:
print(f"{log_prefix} 签到成功")
elif error_code == "160002":
exist_count += 1
print(f"{log_prefix} {result.get('error_msg', '今日已签到')}")
elif error_code == "340006":
shield_count += 1
print(f"{log_prefix} 贴吧已被屏蔽")
else:
error_count += 1
print(f"{log_prefix} 签到失败,错误: {result.get('error_msg', '未知错误')}")
except Exception as e:
error_count += 1
print(f"{log_prefix} 签到异常: {e!s}")
return {
"total": total,
"success": success_count,
"exist": exist_count,
"shield": shield_count,
"error": error_count,
}
def main(self) -> str:
try:
tbs, user_name = self.get_user_info()
if not tbs:
return f"账号: {user_name}\n登录状态: Cookie可能已过期"
forums = self.get_favorite()
if forums:
stats = self.sign_forums(forums, tbs)
msg = [
{"name": "帐号信息", "value": user_name},
{"name": "贴吧总数", "value": stats["total"]},
{"name": "签到成功", "value": stats["success"]},
{"name": "已经签到", "value": stats["exist"]},
{"name": "被屏蔽的", "value": stats["shield"]},
{"name": "签到失败", "value": stats["error"]},
]
else:
msg = [
{"name": "帐号信息", "value": user_name},
{"name": "获取贴吧列表失败,无法完成签到", "value": ""},
]
except Exception as e:
msg = [
{"name": "帐号信息", "value": user_name},
{"name": "签到失败", "value": str(e)},
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("TIEBA", [])[0]
print(Tieba(check_item=_check_item).main())
================================================
FILE: dailycheckin/utils/__init__.py
================================================
================================================
FILE: dailycheckin/utils/message.py
================================================
import base64
import hashlib
import hmac
import json
import re
import time
from urllib.parse import quote_plus
import requests
def message2server(sckey, content):
print("server 酱推送开始")
data = {"text": "每日签到", "desp": content.replace("\n", "\n\n")}
requests.post(url=f"https://sc.ftqq.com/{sckey}.send", data=data)
def message2server_turbo(sendkey, content):
data = {"text": "每日签到", "desp": content.replace("\n", "\n\n")}
if match := re.match(r"^sctp(\d+)t", sendkey):
sc3uid = match.group(1)
print("Server 酱³ 推送开始")
url = f"https://{sc3uid}.push.ft07.com/send/{sendkey}.send?tags=DailyCheckin"
else:
print("server 酱 Turbo 推送开始")
url = f"https://sctapi.ftqq.com/{sendkey}.send"
requests.post(url=url, data=data)
def message2coolpush(
coolpushskey,
content,
coolpushqq: bool = True,
coolpushwx: bool = False,
coolpushemail: bool = False,
):
print("Cool Push 推送开始")
params = {"c": content, "t": "每日签到"}
if coolpushqq:
requests.post(url=f"https://push.xuthus.cc/send/{coolpushskey}", params=params)
if coolpushwx:
requests.post(url=f"https://push.xuthus.cc/wx/{coolpushskey}", params=params)
if coolpushemail:
requests.post(url=f"https://push.xuthus.cc/email/{coolpushskey}", params=params)
def message2qmsg(qmsg_key, qmsg_type, content):
print("qmsg 酱推送开始")
params = {"msg": content}
if qmsg_type == "group":
requests.get(url=f"https://qmsg.zendee.cn/group/{qmsg_key}", params=params)
else:
requests.get(url=f"https://qmsg.zendee.cn/send/{qmsg_key}", params=params)
def message2telegram(tg_api_host, tg_proxy, tg_bot_token, tg_user_id, content):
print("Telegram 推送开始")
send_data = {
"chat_id": tg_user_id,
"text": content,
"disable_web_page_preview": "true",
}
if tg_api_host:
url = f"https://{tg_api_host}/bot{tg_bot_token}/sendMessage"
else:
url = f"https://api.telegram.org/bot{tg_bot_token}/sendMessage"
if tg_proxy:
proxies = {
"http": tg_proxy,
"https": tg_proxy,
}
else:
proxies = None
requests.post(url=url, data=send_data, proxies=proxies)
def message2feishu(fskey, content):
print("飞书 推送开始")
data = {"msg_type": "text", "content": {"text": content}}
requests.post(url=f"https://open.feishu.cn/open-apis/bot/v2/hook/{fskey}", json=data)
def message2dingtalk(dingtalk_secret, dingtalk_access_token, content):
print("Dingtalk 推送开始")
timestamp = str(round(time.time() * 1000))
secret_enc = dingtalk_secret.encode("utf-8")
string_to_sign = f"{timestamp}\n{dingtalk_secret}"
string_to_sign_enc = string_to_sign.encode("utf-8")
hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
sign = quote_plus(base64.b64encode(hmac_code))
send_data = {"msgtype": "text", "text": {"content": content}}
requests.post(
url=f"https://oapi.dingtalk.com/robot/send?access_token={dingtalk_access_token}×tamp={timestamp}&sign={sign}",
headers={"Content-Type": "application/json", "Charset": "UTF-8"},
data=json.dumps(send_data),
)
def message2bark(bark_url: str, content):
print("Bark 推送开始")
if not bark_url.endswith("/"):
bark_url += "/"
content = quote_plus(content)
url = f"{bark_url}{content}"
headers = {"Content-type": "application/x-www-form-urlencoded"}
requests.get(url=url, headers=headers)
def message2qywxrobot(qywx_key, content):
print("企业微信群机器人推送开始")
requests.post(
url=f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={qywx_key}",
data=json.dumps({"msgtype": "text", "text": {"content": content}}),
)
def message2qywxapp(
qywx_corpid,
qywx_agentid,
qywx_corpsecret,
qywx_touser,
qywx_media_id,
qywx_origin,
content,
):
print("企业微信应用消息推送开始")
base_url = "https://qyapi.weixin.qq.com"
if qywx_origin:
base_url = qywx_origin
res = requests.get(f"{base_url}/cgi-bin/gettoken?corpid={qywx_corpid}&corpsecret={qywx_corpsecret}")
token = res.json().get("access_token", False)
if qywx_media_id:
data = {
"touser": qywx_touser,
"msgtype": "mpnews",
"agentid": int(qywx_agentid),
"mpnews": {
"articles": [
{
"title": "Dailycheckin 签到通知",
"thumb_media_id": qywx_media_id,
"author": "Sitoi",
"content_source_url": "https://github.com/Sitoi/dailycheckin",
"content": content.replace("\n", "<br>"),
"digest": content,
}
]
},
}
else:
data = {
"touser": qywx_touser,
"agentid": int(qywx_agentid),
"msgtype": "textcard",
"textcard": {
"title": "Dailycheckin 签到通知",
"description": content,
"url": "https://github.com/Sitoi/dailycheckin",
"btntxt": "开源项目",
},
}
requests.post(
url=f"{base_url}/cgi-bin/message/send?access_token={token}",
data=json.dumps(data),
)
def message2pushplus(pushplus_token, content, pushplus_topic=None):
print("Pushplus 推送开始")
data = {
"token": pushplus_token,
"title": "签到通知",
"content": content.replace("\n", "<br>"),
"template": "json",
}
if pushplus_topic:
data["topic"] = pushplus_topic
requests.post(url="http://www.pushplus.plus/send", data=json.dumps(data))
def message2gotify(gotify_url: str, gotify_token: str, gotify_priority: str, content: str) -> None:
print("Gotify 服务启动")
if not gotify_priority:
gotify_priority = "3"
url = f"{gotify_url}/message?token={gotify_token}"
data = {
"title": "Dailycheckin签到通知",
"message": content,
"priority": gotify_priority,
}
response = requests.post(url, data=data).json()
if response.get("id"):
print("Gotify 推送成功!")
else:
print("Gotify 推送失败!")
def message2ntfy(ntfy_url: str, ntfy_topic: str, ntfy_priority: str, content: str) -> None:
def encode_rfc2047(text: str) -> str:
"""将文本编码为符合 RFC 2047 标准的格式"""
encoded_bytes = base64.b64encode(text.encode("utf-8"))
encoded_str = encoded_bytes.decode("utf-8")
return f"=?utf-8?B?{encoded_str}?="
print("Ntfy 服务启动")
if not ntfy_url:
ntfy_url = "https://ntfy.sh"
if not ntfy_priority:
ntfy_priority = "3"
# 使用 RFC 2047 编码 title
encoded_title = encode_rfc2047("Dailycheckin签到通知")
data = content.encode(encoding="utf-8")
headers = {"Title": encoded_title, "Priority": ntfy_priority} # 使用编码后的 title
url = f"{ntfy_url}/{ntfy_topic}"
response = requests.post(url, data=data, headers=headers)
if response.status_code == 200: # 使用 response.status_code 进行检查
print("Ntfy 推送成功!")
else:
print("Ntfy 推送失败!错误信息:", response.text)
def important_notice():
datas = requests.get(url="https://api.github.com/repos/Sitoi/dailycheckin/issues?state=open&labels=通知").json()
if datas:
data = datas[0]
title = data.get("title")
body = data.get("body")
url = data.get("html_url")
notice = f"{title}\n{body}\n详细地址: {url}"
else:
notice = None
return notice
def push_message(content_list: list, notice_info: dict):
dingtalk_secret = notice_info.get("dingtalk_secret")
dingtalk_access_token = notice_info.get("dingtalk_access_token")
fskey = notice_info.get("fskey")
bark_url = notice_info.get("bark_url")
sckey = notice_info.get("sckey")
sendkey = notice_info.get("sendkey")
qmsg_key = notice_info.get("qmsg_key")
qmsg_type = notice_info.get("qmsg_type")
tg_bot_token = notice_info.get("tg_bot_token")
tg_user_id = notice_info.get("tg_user_id")
tg_api_host = notice_info.get("tg_api_host")
tg_proxy = notice_info.get("tg_proxy")
coolpushskey = notice_info.get("coolpushskey")
coolpushqq = notice_info.get("coolpushqq")
coolpushwx = notice_info.get("coolpushwx")
coolpushemail = notice_info.get("coolpushemail")
qywx_key = notice_info.get("qywx_key")
qywx_corpid = notice_info.get("qywx_corpid")
qywx_agentid = notice_info.get("qywx_agentid")
qywx_corpsecret = notice_info.get("qywx_corpsecret")
qywx_touser = notice_info.get("qywx_touser")
qywx_media_id = notice_info.get("qywx_media_id")
qywx_origin = notice_info.get("qywx_origin")
pushplus_token = notice_info.get("pushplus_token")
pushplus_topic = notice_info.get("pushplus_topic")
gotify_url = notice_info.get("gotify_url")
gotify_token = notice_info.get("gotify_token")
gotify_priority = notice_info.get("gotify_priority")
ntfy_url = notice_info.get("ntfy_url")
ntfy_topic = notice_info.get("ntfy_topic")
ntfy_priority = notice_info.get("ntfy_priority")
content_str = "\n————————————\n\n".join(content_list)
merge_push = notice_info.get("merge_push")
message_list = [content_str]
try:
notice = important_notice()
if notice:
message_list.append(notice)
content_list.append(notice)
except Exception as e:
print("获取重要通知失败:", e)
if merge_push is None:
if (
qmsg_key
or coolpushskey
or qywx_touser
or qywx_corpsecret
or qywx_agentid
or bark_url
or pushplus_token
or ntfy_topic
or (gotify_url and gotify_token)
):
merge_push = False
else:
merge_push = True
if not merge_push:
message_list = content_list
for message in message_list:
if qmsg_key:
try:
message2qmsg(qmsg_key=qmsg_key, qmsg_type=qmsg_type, content=message)
except Exception as e:
print("qmsg 推送失败", e)
if coolpushskey:
try:
message2coolpush(
coolpushskey=coolpushskey,
coolpushqq=coolpushqq,
coolpushwx=coolpushwx,
coolpushemail=coolpushemail,
content=message,
)
except Exception as e:
print("coolpush 推送失败", e)
if qywx_touser and qywx_corpid and qywx_corpsecret and qywx_agentid:
try:
message2qywxapp(
qywx_corpid=qywx_corpid,
qywx_agentid=qywx_agentid,
qywx_corpsecret=qywx_corpsecret,
qywx_touser=qywx_touser,
qywx_media_id=qywx_media_id,
qywx_origin=qywx_origin,
content=message,
)
except Exception as e:
print("企业微信应用消息推送失败", e)
if bark_url:
try:
message2bark(bark_url=bark_url, content=message)
except Exception as e:
print("Bark 推送失败", e)
if dingtalk_access_token and dingtalk_secret:
try:
message2dingtalk(
dingtalk_secret=dingtalk_secret,
dingtalk_access_token=dingtalk_access_token,
content=message,
)
except Exception as e:
print("钉钉推送失败", e)
if fskey:
try:
message2feishu(fskey=fskey, content=message)
except Exception as e:
print("飞书推送失败", e)
if sckey:
try:
message2server(sckey=sckey, content=message)
except Exception as e:
print("Server 推送失败", e)
if sendkey:
try:
message2server_turbo(sendkey=sendkey, content=message)
except Exception as e:
print("Server Turbo 推送失败", e)
if qywx_key:
try:
message2qywxrobot(qywx_key=qywx_key, content=message)
except Exception as e:
print("企业微信群机器人推送失败", e)
if pushplus_token:
try:
message2pushplus(
pushplus_token=pushplus_token,
content=message,
pushplus_topic=pushplus_topic,
)
except Exception as e:
print("Pushplus 推送失败", e)
if tg_user_id and tg_bot_token:
try:
message2telegram(
tg_api_host=tg_api_host,
tg_proxy=tg_proxy,
tg_user_id=tg_user_id,
tg_bot_token=tg_bot_token,
content=message,
)
except Exception as e:
print("Telegram 推送失败", e)
if gotify_url and gotify_token:
try:
message2gotify(
gotify_url=gotify_url,
gotify_token=gotify_token,
gotify_priority=gotify_priority,
content=message,
)
except Exception as e:
print("Gotify 推送失败", e)
if ntfy_topic:
try:
message2ntfy(
ntfy_url=ntfy_url,
ntfy_topic=ntfy_topic,
ntfy_priority=ntfy_priority,
content=message,
)
except Exception as e:
print("Ntfy 推送失败", e)
if __name__ == "__main__":
print(important_notice())
================================================
FILE: dailycheckin/v2ex/__init__.py
================================================
================================================
FILE: dailycheckin/v2ex/main.py
================================================
import json
import os
import re
import requests
import urllib3
from dailycheckin import CheckIn
urllib3.disable_warnings()
class V2ex(CheckIn):
name = "V2EX 论坛"
def __init__(self, check_item):
self.check_item = check_item
@staticmethod
def sign(session):
msg = []
response = session.get(url="https://www.v2ex.com/mission/daily", verify=False)
pattern = (
r"<input type=\"button\" class=\"super normal button\""
r" value=\".*?\" onclick=\"location\.href = \'(.*?)\';\" />"
)
urls = re.findall(pattern=pattern, string=response.text)
url = urls[0] if urls else None
if url is None:
return [{"name": "签到失败", "value": "cookie 可能过期"}]
elif url != "/balance":
headers = {"Referer": "https://www.v2ex.com/mission/daily"}
data = {"once": url.split("=")[-1]}
_ = session.get(
url="https://www.v2ex.com" + url,
verify=False,
headers=headers,
params=data,
)
response = session.get(url="https://www.v2ex.com/balance", verify=False)
total = re.findall(
pattern=r"<td class=\"d\" style=\"text-align: right;\">(\d+\.\d+)</td>",
string=response.text,
)
total = total[0] if total else "签到失败"
today = re.findall(
pattern=r'<td class="d"><span class="gray">(.*?)</span></td>',
string=response.text,
)
today = today[0] if today else "签到失败"
username = re.findall(
pattern=r"<a href=\"/member/.*?\" class=\"top\">(.*?)</a>",
string=response.text,
)
username = username[0] if username else "用户名获取失败"
msg += [
{"name": "帐号信息", "value": username},
{"name": "今日签到", "value": today},
{"name": "帐号余额", "value": total},
]
response = session.get(url="https://www.v2ex.com/mission/daily", verify=False)
data = re.findall(pattern=r"<div class=\"cell\">(.*?)天</div>", string=response.text)
data = data[0] + "天" if data else "获取连续签到天数失败"
msg += [
{"name": "签到天数", "value": data},
]
return msg
def main(self):
cookie = {item.split("=")[0]: item.split("=")[1] for item in self.check_item.get("cookie").split("; ")}
session = requests.session()
if self.check_item.get("proxy", ""):
proxies = {
"http": self.check_item.get("proxy", ""),
"https": self.check_item.get("proxy", ""),
}
session.proxies.update(proxies)
requests.utils.add_dict_to_cookiejar(session.cookies, cookie)
session.headers.update(
{
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.88 Safari/537.36 Edg/87.0.664.66",
"accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9",
"accept-language": "zh-CN,zh;q=0.9,en;q=0.8",
}
)
msg = self.sign(session=session)
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("V2EX", [])[0]
print(V2ex(check_item=_check_item).main())
================================================
FILE: dailycheckin/youdao/__init__.py
================================================
================================================
FILE: dailycheckin/youdao/main.py
================================================
import json
import os
import requests
from dailycheckin import CheckIn
class YouDao(CheckIn):
name = "有道云笔记"
def __init__(self, check_item):
self.check_item = check_item
@staticmethod
def sign(cookies):
ad_space = 0
refresh_cookies_res = requests.get("http://note.youdao.com/login/acc/pe/getsess?product=YNOTE", cookies=cookies)
cookies = dict(refresh_cookies_res.cookies)
url = "https://note.youdao.com/yws/api/daupromotion?method=sync"
res = requests.post(url=url, cookies=cookies)
if "error" not in res.text:
checkin_response = requests.post(
url="https://note.youdao.com/yws/mapi/user?method=checkin",
cookies=cookies,
)
for i in range(3):
ad_response = requests.post(
url="https://note.youdao.com/yws/mapi/user?method=adRandomPrompt",
cookies=cookies,
)
ad_space += ad_response.json().get("space", 0) // 1048576
if "reward" in res.text:
sync_space = res.json().get("rewardSpace", 0) // 1048576
checkin_space = checkin_response.json().get("space", 0) // 1048576
space = sync_space + checkin_space + ad_space
youdao_message = f"+{space}M"
else:
youdao_message = "获取失败"
else:
youdao_message = "Cookie 可能过期"
return youdao_message
def main(self):
youdao_cookie = {item.split("=")[0]: item.split("=")[1] for item in self.check_item.get("cookie").split("; ")}
try:
ynote_pers = youdao_cookie.get("YNOTE_PERS", "")
uid = ynote_pers.split("||")[-2]
except Exception as e:
print(f"获取账号信息失败: {e}")
uid = "未获取到账号信息"
msg = self.sign(cookies=youdao_cookie)
msg = [
{"name": "帐号信息", "value": uid},
{"name": "获取空间", "value": msg},
]
msg = "\n".join([f"{one.get('name')}: {one.get('value')}" for one in msg])
return msg
if __name__ == "__main__":
with open(
os.path.join(os.path.dirname(os.path.dirname(__file__)), "config.json"),
encoding="utf-8",
) as f:
datas = json.loads(f.read())
_check_item = datas.get("YOUDAO", [])[0]
print(YouDao(check_item=_check_item).main())
================================================
FILE: docker/.dockerignore
================================================
config.template.json
crontab_list.sh
Makefile
docker-compose.yml
================================================
FILE: docker/Dockerfile
================================================
FROM python:3.9-alpine
WORKDIR /dailycheckin
COPY ./start.sh /usr/local/bin
RUN set -ex \
&& apk update && apk upgrade\
&& apk add --no-cache gcc g++ make libffi-dev openssl-dev\
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& echo "Asia/Shanghai" > /etc/timezone \
&& chmod +x /usr/local/bin/start.sh \
&& pip install dailycheckin --upgrade \
&& ln -s /root/.local/bin/dailycheckin /usr/bin/dailycheckin
ADD . /dailycheckin
ENTRYPOINT ["start.sh"]
================================================
FILE: docker/Makefile
================================================
.PHONY: build up stop pull logs down exec buildx pushx
buildx:
docker buildx build --platform=linux/arm/v6,linux/arm/v7,linux/arm64,linux/amd64 -t sitoi/dailycheckin:latest .
pushx:
docker buildx build --platform=linux/arm/v6,linux/arm/v7,linux/arm64,linux/amd64 -t sitoi/dailycheckin:latest . --push
build:
docker-compose build --no-cache
up:
docker-compose up -d
stop:
docker-compose stop
down:
docker-compose down
pull:
docker-compose pull
logs:
docker-compose logs -f
exec:
docker exec -it dailycheckin sh
================================================
FILE: docker/config.template.json
================================================
{
"BARK_URL": "",
"COOLPUSHEMAIL": true,
"COOLPUSHQQ": true,
"COOLPUSHSKEY": "",
"COOLPUSHWX": true,
"DINGTALK_ACCESS_TOKEN": "",
"DINGTALK_SECRET": "",
"FSKEY": "",
"PUSHPLUS_TOKEN": "",
"PUSHPLUS_TOPIC": "",
"QMSG_KEY": "",
"QMSG_TYPE": "",
"QYWX_AGENTID": "",
"QYWX_CORPID": "",
"QYWX_CORPSECRET": "",
"QYWX_KEY": "",
"QYWX_MEDIA_ID": "",
"QYWX_TOUSER": "",
"SCKEY": "",
"SENDKEY": "",
"TG_API_HOST": "",
"TG_BOT_TOKEN": "",
"TG_PROXY": "",
"TG_USER_ID": "",
"MERGE_PUSH": "",
"ACFUN": [
{
"password": "Sitoi",
"phone": "18888xxxxxx"
},
{
"password": "多账号 密码填写,请参考上面",
"phone": "多账号 手机号填写,请参考上面"
}
],
"ALIYUN": [
{
"refresh_token": "599dcf65xxxxxx"
},
{
"refresh_token": "多账号 refresh_token"
}
],
"AOLAXING": [
{
"cookie": "BT_AUTO_tt_common=; Hm_lpvt_7fc3681c21a26a2022ae0ca72e2d6fa5=xxxxxx; BT_LOGIN_tt_common=:187xxxxxx; Hm_lvt_7fc3681c21a26a2022ae0ca72e2d6fa5=xxxxxx;"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"BAIDU": [
{
"data_url": "https://fastly.jsdelivr.net/gh/Sitoi/Sitoi.github.io/baidu_urls.txt",
"submit_url": "http://data.zz.baidu.com/urls?site=https://sitoi.cn&token=xxxxxx",
"times": 10
},
{
"data_url": "多账号 data_url 链接地址,以实际获取为准",
"submit_url": "多账号 submit_url 链接地址,以实际获取为准",
"times": 10
}
],
"BAIDUWP": [
{
"cookie": "BAIDUID=xxx:FG=1; BAIDUID_BFESS=xxx:FG=1; xxx"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"BILIBILI": [
{
"coin_num": 0,
"coin_type": 1,
"cookie": "_uuid=xxxxxx; rpdid=xxxxxx; LIVE_BUVID=xxxxxx; PVID=xxxxxx; blackside_state=xxxxxx; CURRENT_FNVAL=xxxxxx; buvid3=xxxxxx; fingerprint3=xxxxxx; fingerprint=xxxxxx; buivd_fp=xxxxxx; buvid_fp_plain=xxxxxx; DedeUserID=xxxxxx; DedeUserID__ckMd5=xxxxxx; SESSDATA=xxxxxx; bili_jct=xxxxxx; bsource=xxxxxx; finger=xxxxxx; fingerprint_s=xxxxxx;",
"silver2coin": true
},
{
"coin_num": 0,
"coin_type": 1,
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)",
"silver2coin": true
}
],
"ENSHAN": [
{
"cookie": "fpv=xxxxxx; yd_captcha_token=xxxxxx; _dx_captcha_cid=xxxxxx; _dx_uzZo5y=xxxxxx; _dx_FMrPY6=xxxxxx; _dx_app_captchadiscuzpluginbydingxiang2017=xxxxxx; TWcq_2132_pc_size_c=0; TWcq_2132_saltkey=xxxxxx; TWcq_2132_lastvisit=xxxxxx; TWcq_2132_sendmail=1; _dx_captcha_vid=xxxxxx; TWcq_2132_sid=Wyv5Ps; TWcq_2132_ulastactivity=xxxxxx; TWcq_2132_auth=xxxxxx; TWcq_2132_lastcheckfeed=xxxxxx; TWcq_2132_lip=xxxxxx; TWcq_2132_connect_is_bind=1; TWcq_2132_nofavfid=1; TWcq_2132_lastact=xxxxxx"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"FNNASCLUB": [
{
"cookie": "pvRK_2132_saltkey=xxxx;xxxxxxx"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"IMAOTAI": [
{
"city": "上海市",
"lat": "3.025626",
"lng": "3.025626",
"mobile": "18888xxxxxx",
"province": "上海市",
"token": "eyJxxxxxx",
"userid": "1xxxxxx4"
},
{
"city": "多账号 城市",
"lat": "多账号 纬度",
"lng": "多账号 经度",
"mobile": "多账号 手机号",
"province": "多账号 省份",
"token": "多账号 token",
"userid": "多账号 用户 id"
}
],
"IQIYI": [
{
"cookie": "__dfp=xxxxxx; QP0013=xxxxxx; QP0022=xxxxxx; QYABEX=xxxxxx; P00001=xxxxxx; P00002=xxxxxx; P00003=xxxxxx; P00007=xxxxxx; QC163=xxxxxx; QC175=xxxxxx; QC179=xxxxxx; QC170=xxxxxx; P00010=xxxxxx; P00PRU=xxxxxx; P01010=xxxxxx; QC173=xxxxxx; QC180=xxxxxx; P00004=xxxxxx; QP0030=xxxxxx; QC006=xxxxxx; QC007=xxxxxx; QC008=xxxxxx; QC010=xxxxxx; nu=xxxxxx; __uuid=xxxxxx; QC005=xxxxxx;"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"KGQQ": [
{
"cookie": "muid=xxxxxx; uid=xxxxxx; userlevel=xxxxxx; openid=xxxxxx; openkey=xxxxxx; opentype=xxxxxx; qrsig=xxxxxx; pgv_pvid=xxxxxx;"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"MIMOTION": [
{
"max_step": "20000",
"min_step": "10000",
"password": "Sitoi",
"phone": "18888xxxxxx"
},
{
"max_step": "多账号 最大步数填写,请参考上面",
"min_step": "多账号 最小步数填写,请参考上面",
"password": "多账号 密码填写,请参考上面",
"phone": "多账号 手机号填写,请参考上面"
}
],
"SMZDM": [
{
"cookie": "__ckguid=xxxxxx"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"TIEBA": [
{
"cookie": "BIDUPSID=xxxxxx; PSTM=xxxxxx; BAIDUID=xxxxxx; BAIDUID_BFESS=xxxxxx; delPer=xxxxxx; PSINO=xxxxxx; H_PS_PSSID=xxxxxx; BA_HECTOR=xxxxxx; BDORZ=xxxxxx; TIEBA_USERTYPE=xxxxxx; st_key_id=xxxxxx; BDUSS=xxxxxx; BDUSS_BFESS=xxxxxx; STOKEN=xxxxxx; TIEBAUID=xxxxxx; ab_sr=xxxxxx; st_data=xxxxxx; st_sign=xxxxxx;"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
],
"V2EX": [
{
"cookie": "_ga=xxxxxx; __cfduid=xxxxxx; PB3_SESSION=xxxxxx; A2=xxxxxx; V2EXSETTINGS=xxxxxx; V2EX_REFERRER=xxxxxx; V2EX_LANG=xxxxxx; _gid=xxxxxx; V2EX_TAB=xxxxxx;",
"proxy": "使用代理的信息,无密码例子: http://127.0.0.1:1080 有密码例子: http://username:password@127.0.0.1:1080"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)",
"proxy": "使用代理的信息,无密码例子: http://127.0.0.1:1080 有密码例子: http://username:password@127.0.0.1:1080"
}
],
"YOUDAO": [
{
"cookie": "JSESSIONID=xxxxxx; __yadk_uid=xxxxxx; OUTFOX_SEARCH_USER_ID_NCOO=xxxxxx; YNOTE_SESS=xxxxxx; YNOTE_PERS=xxxxxx; YNOTE_LOGIN=xxxxxx; YNOTE_CSTK=xxxxxx; _ga=xxxxxx; _gid=xxxxxx; _gat=xxxxxx; PUBLIC_SHARE_18a9dde3de846b6a69e24431764270c4=xxxxxx;"
},
{
"cookie": "多账号 cookie 填写,请参考上面,cookie 以实际获取为准(遇到特殊字符如双引号\" 请加反斜杠转义)"
}
]
}
================================================
FILE: docker/crontab_list.sh
================================================
##############默认任务##############
# 每 12 小时更新 Pipy 包,如果不需要更新 pypi 包请注释掉下面这行
0 */12 * * * echo "定时任务更新依赖..." && pip install dailycheckin --upgrade --user >> /dailycheckin/logs/update-pypi.log 2>&1
# 每天的 23:50 分清理一次日志
50 23 */2 * * rm -rf /dailycheckin/logs/*.log
##############每日签到一次任务##############
# 每日签到(9:00 执行全部签到)
0 9 * * * cd /dailycheckin && dailycheckin >> /dailycheckin/logs/dailycheckin.log 2>&1
================================================
FILE: docker/default_task.sh
================================================
#!/bin/sh
set -e
export LANG="zh_CN.UTF-8"
echo "定时任务更新依赖..."
pip install dailycheckin --upgrade --user
echo "Load the latest crontab task file..."
echo "加载最新的定时任务文件..."
crontab /dailycheckin/cron/crontab_list.sh
================================================
FILE: docker/docker-compose.yml
================================================
version: '3'
services:
dailycheckin:
image: sitoi/dailycheckin:latest
container_name: dailycheckin
restart: always
tty: true
volumes:
- ./config/:/dailycheckin/config/
- ./logs/:/dailycheckin/logs/
- ./cron/:/dailycheckin/cron/
================================================
FILE: docker/start.sh
================================================
#!/bin/sh
set -e
export LANG="zh_CN.UTF-8"
CRONTAB_FILE="/dailycheckin/cron/crontab_list.sh"
echo "安装最新依赖..."
pip install dailycheckin --upgrade --user
echo "加载最新的定时任务文件..."
crontab $CRONTAB_FILE
if [ $CRONTAB_FILE ]; then
chmod -R 777 $CRONTAB_FILE
fi
echo "启动 crondtab 定时任务主进程..."
crond -f
================================================
FILE: docker_start.sh
================================================
#!/bin/bash
echo "在当前目录下创建 config 和 cron 文件夹"
mkdir -p config
mkdir -p cron
CONFIG_FILE="config/config.json"
CRONTAB_FILE="cron/crontab_list.sh"
if [ ! -f "$CONFIG_FILE" ]; then
echo "config.json 不存在. 开始下载默认文件..."
curl https://fastly.jsdelivr.net/gh/sitoi/dailycheckin@main/docker/config.template.json -o $CONFIG_FILE
else
echo "config.json 已存在. 跳过下载。"
fi
if [ ! -f "$CRONTAB_FILE" ]; then
echo "crontab_list.sh 不存在. 开始下载默认文件..."
curl https://fastly.jsdelivr.net/gh/sitoi/dailycheckin@main/docker/crontab_list.sh -o $CRONTAB_FILE
else
echo "crontab_list.sh 已存在. 跳过下载。"
fi
docker --version
if [ $? -ne 0 ];then
echo "未安装 docker ,请先安装 docker 再运行脚本。"
else
echo "docker 环境存在,检测 docker-compose 环境是否安装..."
docker-compose --version || docker compose version && alias docker-compose="docker compose"
if [ $? -ne 0 ];then
echo "未安装 docker-compose,将使用 docker 命令启动容器..."
echo "开始通过 docker 命令创建容器"
docker pull sitoi/dailycheckin:latest
docker run -d -v $(pwd)/config:/dailycheckin/config \
-v $(pwd)/logs:/dailycheckin/logs \
-v $(pwd)/cron:/dailycheckin/cron \
--name dailycheckin \
--restart always \
sitoi/dailycheckin:latest
else
echo "docker-compose 环境存在,将使用 docker-compose 命令启动容器..."
echo "下载 docker-compose.yml 文件"
curl -O https://fastly.jsdelivr.net/gh/sitoi/dailycheckin@main/docker/docker-compose.yml
echo "开始通过 docker-compose 命令创建容器"
docker-compose pull
docker-compose up -d
fi
fi
================================================
FILE: docs/components/CardList.tsx
================================================
import { Card, Cards } from 'nextra/components'
import type { ReactNode } from 'react'
interface CardItem {
title: string
href: string
icon?: ReactNode
children?: ReactNode
}
interface CardListProps {
cards: CardItem[]
}
const defaultCards: CardItem[] = [
{ title: 'AcFun', href: '/settings/acfun' },
{ title: '奥拉星', href: '/settings/aolaxing' },
{ title: '阿里云盘', href: '/settings/aliyun' },
{ title: 'Baidu 站点提交', href: '/settings/baidu' },
{ title: '百度网盘会员', href: '/settings/baiduwp' },
{ title: 'Bilibili', href: '/settings/bilibili' },
{ title: '恩山无线论坛', href: '/settings/enshan' },
{ title: '飞牛 NAS', href: '/settings/fnnas' },
{ title: 'i茅台', href: '/settings/imaotai' },
{ title: '爱奇艺', href: '/settings/iqiyi' },
{ title: '全民 K 歌', href: '/settings/kgqq' },
{ title: '小米运动', href: '/settings/mimotion' },
{ title: '什么值得买', href: '/settings/smzdm' },
{ title: '百度贴吧', href: '/settings/tieba' },
{ title: 'V2EX', href: '/settings/v2ex' },
{ title: '有道云笔记', href: '/settings/youdao' },
]
export default function CardList({ cards = defaultCards }: CardListProps) {
return (
<Cards>
{cards.map((item) => (
<Card
key={item.href}
title={item.title}
href={item.href}
icon={item.icon}
>
{item.children}
</Card>
))}
</Cards>
)
}
================================================
FILE: docs/components/counters.module.css
================================================
.counter {
border: 1px solid #ccc;
border-radius: 5px;
padding: 2px 6px;
margin: 12px 0 0;
}
================================================
FILE: docs/components/counters.tsx
================================================
// Example from https://beta.reactjs.org/learn
import { useState } from 'react'
import styles from './counters.module.css'
function MyButton() {
const [count, setCount] = useState(0)
function handleClick() {
setCount(count + 1)
}
return (
<div>
<button
onClick={handleClick}
className={styles.counter}
>
Clicked {count} times
</button>
</div>
)
}
export default function MyApp() {
return <MyButton />
}
================================================
FILE: docs/next-env.d.ts
================================================
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
================================================
FILE: docs/next.config.js
================================================
/** @type {import('next').NextConfig} */
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.tsx',
})
const isProduction = process.env.NODE_ENV === 'production'
const assetPrefix = isProduction ? '/dailycheckin' : ''
const nextConfig = {
images: {
unoptimized: true,
},
reactStrictMode: true,
swcMinify: true,
trailingSlash: true,
assetPrefix,
basePath: assetPrefix,
output: 'export',
}
module.exports = {
...withNextra(),
...nextConfig,
}
================================================
FILE: docs/package.json
================================================
{
"name": "dailycheckin-docs",
"version": "2025-09-28",
"description": "DailyCheckIn docs",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"export": "next build && touch out/.nojekyll",
"deploy": "gh-pages -d out -t true"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Sitoi/dailycheckin.git"
},
"author": "Sitoi",
"license": "MIT",
"bugs": {
"url": "https://github.com/Sitoi/dailycheckin/issues"
},
"homepage": "https://github.com/Sitoi/dailycheckin#readme",
"dependencies": {
"next": "14.1.0",
"nextra": "2.13.3",
"nextra-theme-docs": "2.13.3",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@types/node": "20.11.19",
"typescript": "^5.3.3",
"gh-pages": "^6.1.1"
}
}
================================================
FILE: docs/pages/_meta.json
================================================
{
"index": "项目介绍",
"install": "部署方法",
"settings": "配置说明",
"history": "更新日志"
}
================================================
FILE: docs/pages/history.mdx
================================================
import { Callout } from 'nextra/components'
## 2025-12-09

### ✨ 功能
- 新增「飞牛 Nas」签到
### 🐛 修复
- 修复「恩山」接口失效
- 修复无法检测到「百度网盘」的问题
## 2025-09-28

### ✨ 功能
- 新增「百度网盘会员签到和答题」签到
### 🐛 修复
- 修复「小米运动」接口失效
## 2025-05-09

### 🐛 修复
- 修复「什么值得买」签到奖励信息解析错误
- 重构「百度贴吧」签到逻辑提高稳定性,解决卡住的问题
### 🔥 删除
- 移除「爱奇艺」无效签到及任务逻辑
## 2025-01-07

### ✨ 功能
- 新增「i 茅台」申购蛇茅申购 🐍
```json copy
{
"11318": "53%vol 500ml贵州茅台酒(乙巳蛇年)",
"11317": "53%vol 500ml贵州茅台酒(笙乐飞天)",
"11319": "53%vol 375mlx2贵州茅台酒(乙巳蛇年)",
"2478": "53%vol 500ml贵州茅台酒(珍品)",
"11240": "53%vol 500ml 茅台1935·中国国家地理文创酒(喜逢大运河)"
}
```
默认配置申购 `["11318", "11319"]`
- 新增「ntfy」和「gotify」和「Server 酱 ³」推送方式
### 🐛 修复
- 企业微信反向代理地址参数 QYWX_ORIGIN 无法获取的问题
## 2024-10-08

### 🐛 修复
- 修复「小米运动」获取时间戳失败的问题
## 2024-05-15

### 🐛 修复
- 修复「爱奇艺」签到失效的问题
## 2024-03-19

### 🐛 修复
- 修复「爱奇艺」摇一摇失败的 BUG
## 2024-03-11

### 🐛 修复
- 兼容 docker compose
- 修复「企业微信应用消息」 添加反代设置,修复非可信 IP 的问题。
https://developer.work.weixin.qq.com/document/path/90664#%E5%8F%AF%E4%BF%A1ip
## 2024-03-07

### 🐛 修复
- 修复「Bark」消息不通知的 BUG
## 2024-02-27

### 🐛 修复
- 修复「爱奇艺」非会员用户脚本错误的 BUG
- 修复「i 茅台」领取耐力值失败的 BUG
## 2024-02-22

### 🐛 修复
- 修复「V2EX」日志错误的 BUG
- 修复「阿里云盘」过期提示
### 📃 文档
- 修改获取 cookie 教程
## 2024-02-20

### ✨ 功能
- 新增「小米运动」支持邮箱登录
- 新增「爱奇艺」抽白金会员活动
- 活动链接:https://vip.iqiyi.com/m-design/Else-2312LargeScreenIndependentPage/2312LargeScreenIndependentPage/index.html
## 2024-02-16

### ✨ 功能
- 新增「i 茅台」支持自定义申购选择
```json copy
{
"10941": "53%vol 500ml贵州茅台酒(甲辰龙年)",
"10942": "53%vol 375ml×2贵州茅台酒(甲辰龙年)",
"10056": "53%vol 500ml茅台1935",
"2478": "53%vol 500ml贵州茅台酒(珍品)"
}
```
默认配置申购 `["10941", "10942"]`
### 🐛 修复
- 修复「爱奇艺」逛会员优选任务
## 2024-02-09

### ✨ 功能
- 新增「爱奇艺」每日摇一摇功能
### 📃 文档
- 完善「i 茅台」配置获取教程
- 修复「百度贴吧」 cookie 获取方式
## 2024-02-06

### ✨ 功能
- 新增「奥拉星」签到
### 💄 优化
- 优化「什么值得买」日志输出
- 优化「i 茅台」日志输出
### 📃 文档
- 修复多个 cookie 获取方式
## 2024-01-20

### ✨ 功能
- 新增「恩山无线论坛」签到
## 2024-01-16

### 🐛 修复
- 修复「爱奇艺」每日签到 BUG
### 📄 文档
- 更新 群晖 部署教程
## 2024-01-14

### ✨ 功能
- 新增「爱奇艺」刷观看时长、领域 VIP7 升级星钻会员等功能
### 📦 部署
- 更新 Docker 部署
- 优化自定义定时任务方式(建议优化)
### ⚠️ 建议
<Callout
type="warning"
emoji="⚠️"
>
建议 Docker 用户 和 群晖用户 升级 Docker Image。
</Callout>
1. 备份 config.json 文件
2. 更新 image 镜像{' '}
```bash copy
curl https://fastly.jsdelivr.net/gh/sitoi/dailycheckin@main/docker_start.sh | bash
```
<Callout
type="warning"
emoji="⚠️"
>
建议 其他方式部署的用户,更改定时时间到早上 09:00-10:00(茅台申购时间段)。
</Callout>
1. 修改 crontab 定时配置即可
## 2024-01-13

### ✨ 功能
- 新增「阿里云盘」签到
- 新增「i 茅台」申购
- 新增「什么值得买」签到
### 🐛 修复
- 修复「bilibili」大会员奖励领取
### 🔥 删除
- 删除「Fa 米家」
### 📃 文档
- 详细说明每个签到信息获取方式
- 删除「腾讯云函数」部署(收费了)
- 删除「阿里云函数」部署(收费了)
- 删除「elecV2P」部署
## 2024-01-07

### 🐛 修复
- 修复 Bilibili 兑换银瓜子 BUG
## 2023-10-18
- 
### 🔥 删除
- 删除失效脚本
## 2023-02-21
- 
### 🐛 修复
- 修复&删除失效脚本
## 2022-04-26
- 
### 🐛 修复
- 修复【百度贴吧】签到功能
### 🔥 删除
- 删除【吾爱破解】&【网易云音乐】
## 2022-03-17
- 
### ✨ 功能
- 新增【多看阅读】延期功能
- 新增【Bilibili】银瓜子兑换功能
- 新增【爱奇艺】WEB 签到功能
### 🐛 修复
- 修复【爱奇艺】签到功能
## 2021-11-04
- 
### ✨ 功能
- 新增【联通沃邮箱】网页端和客户端任务
- 新增【联通沃邮箱】是否 21 天断签配置
### 🐛 修复
- 修复【联通沃邮箱】俱乐部签到
### 🔥 删除
- 移除【联通沃邮箱】拼图活动
## 2021-10-13
- 
- 修复【联通沃邮箱】脚本
- 完善【欢太商城】脚本
- 修复【pushplus 推送】限制,改为分开推送
- 添加最新版本内容推送
## 2021-10-11
- 
### 🐛 修复
- 修复【联通沃邮箱】脚本
## 2021-10-09
- 
### ✨ 功能
- 添加推送合并或拆分功能
### 💄 优化
- 优化企业微信推送
## 2021-09-22
- 
### ✨ 功能
- 添加【时光相册】签到脚本
### 💄 优化
- 优化日志输出
- Bark 通知改为分批发送
### 🐛 修复
- 修复【联通营业厅】日志错误
## 2021-09-20
- 
### ✨ 功能
- 添加【联通营业厅】脚本
- 更新【联通沃邮箱】每日签到脚本(21 天自动断签)
### 💄 优化
- 优化配置文件
### 🔥 删除
- 移除【每日天气】
## 2021-09-20
- 
### ✨ 功能
- 添加【欢太商城】脚本
### 💄 优化
- 优化项目结构
## 2021-09-19
- 
### 💄 优化
- 优化日志输出
### 🔥 删除
- 移除每日一句脚本
## 2021-09-03
- 
### ✨ 功能
- 适配青龙
- 支持指定运行某个脚本
### 🐛 修复
- 修复【小米运动】签到脚本
- 修复【爱奇艺】签到脚本
## 2021-08-18
- 
### 🐛 修复
- 修复【小米运动】签到脚本
## 2021-07-29
- 
### ✨ 功能
- 添加【飞书】推送功能
### 🐛 修复
- 修复【天翼云】签到脚本
- 修复【AcFun】签到脚本
## 2021-07-05
- 
### 🐛 修复
- 修复【Bilibili】签到脚本
## 2021-06-01
- 
### 🔥 删除
- 删除【联通】&【WPS】签到脚本
## 2021-05-30
- 
### 🐛 修复
- 更新【联通沃邮箱】每日签到脚本
## 2021-04-28
### ✨ 功能
- 添加【联通沃邮箱】每日签到脚本 感谢水友`@什么大风大浪都见过` 提供脚本
## 2021-04-07
### ✨ 功能
- 添加【王者营地】每日签到脚本
- 添加【CSDN】每日签到脚本
- 添加【AcFun】每日分享任务功能
## 2021-03-30
### ✨ 功能
- 添加【微博】每日签到脚本
- 添加【多看阅读】每日签到脚本
## 2021-03-16
### ✨ 功能
- 添加【智友邦】每日签到脚本
## 2021-03-10
### ✨ 功能
- 添加【爱奇艺】10s 任务
## 2021-03-09
### ✨ 功能
- 添加【pushplus】推送功能
- 添加【配置文件】GitHub Actions 使用整个 config.json 配置文件
## 2021-03-06
### ✨ 功能
- 添加【和彩云】签到和抽奖功能
## 2021-03-03
### ✨ 功能
- 添加【MEIZU 社区】签到和抽奖功能
## 2021-03-02
### ✨ 功能
- 添加【企业微信群机器人】推送功能
- 添加【企业微信应用消息】推送功能
## 2021-03-01
### ✨ 功能
- 添加【哔咔漫画】每日签到脚本
- 添加【芒果 TV】每日签到脚本
## 2021-02-23
### ✨ 功能
- 添加【WPS】每日签到脚本
- 添加【吾爱破解】每日签到脚本
## 2021-02-21
### ✨ 功能
- 添加【全民 K 歌】VIP 每日签到脚本
## 2021-02-20
### ✨ 功能
- 添加【server 酱 turbo 版】推送功能
## 2021-01-27
### ✨ 功能
- 添加【天翼云盘】每日签到脚本
## 2021-01-22
### ✨ 功能
- 添加【AcFun】每日签到脚本
## 2021-01-19
### ✨ 功能
- 添加【Bark】推送功能
## 2021-01-16
### ✨ 功能
- 添加【小米运动】刷步数功能
## 2021-01-07
### ✨ 功能
- 添加【什么值得买】每日签到脚本
- 添加【咔叽网单】每日签到脚本
- 添加【V2EX】每日签到脚本
## 2021-01-03
### ✨ 功能
- 添加【联通】每日签到脚本
## 2020-12-22
### ✨ 功能
- 添加【Cool Push】推送功能
## 2020-12-21
### ✨ 功能
- 添加【bilibili】每日签到脚本
- 添加【百度贴吧】每日签到脚本
## 2020-12-19
### ✨ 功能
- 添加【Fa 米家 App】每日签到脚本
## 2020-12-10
### ✨ 功能
- 添加【一加手机社区官方论坛】每日签到脚本
## 2020-12-07
### ✨ 功能
- 添加【每日天气】预报
- 添加【每日一句】获取
## 2020-12-06
### ✨ 功能
- 添加【网易云音乐】每日签到脚本
- 添加【腾讯视频】每日签到脚本
- 添加【吾爱破解】每日签到脚本
- 添加【有道云笔记】每日签到脚本
- 添加【爱奇艺】每日签到脚本
- 添加【百度站点】每日提交脚本
================================================
FILE: docs/pages/index.md
================================================
<div align="center">
<img src="https://socialify.git.ci/Sitoi/dailycheckin/image?font=Rokkitt&forks=1&issues=1&language=1&name=1&owner=1&pattern=Circuit%20Board&pulls=1&stargazers=1&theme=Dark">
<h1>DailyCheckIn</h1>
基于「Docker」/「青龙面板」/「群晖」/「本地」的每日签到脚本
<!-- SHIELD GROUP -->
<div id="shield">
<style>
#shield img {
display: inline-block;
}
</style>
[![][github-releases-shield]][github-releases-link]
[![][pypi-version-shield]][pypi-version-link]
[![][github-release-date-shield]][github-release-date-link]
[![][github-stars-shield]][github-stars-link]
[![][github-forks-shield]][github-forks-link]
[![][github-issues-shield]][github-issues-link]
[![][github-contributors-shield]][github-contributors-link]
[![][python-version-shield]][python-version-link]
[![][pypi-dm-shield]][pypi-dm-link]
[![][docker-pull-shield]][docker-pull-link]
[![][docker-size-shield]][docker-size-link]
[![][docker-stars-shield]][docker-stars-link]
[![][github-license-shield]][github-license-link]
<!-- SHIELD GROUP -->
</div>
</div>
## ✨ 特性
- 📦 支持 Pypi 包安装
- 💻 支持多个平台部署
- ⚙️ 支持多个平台签到
- 📢 支持多个平台通知
- ♾️ 支持多个账号签到
- 🕙 支持定时任务设置
- 🆙 支持项目自动更新
## 🦄 教程
[https://sitoi.github.io/dailycheckin/](https://sitoi.github.io/dailycheckin/)
## 🧾 列表
🟢: 正常运行 🔴: 脚本暂不可用 🔵: 可以执行(需更新) 🟡: 待测试 🟤: 看脸
| 状态 | 任务名称 | 名称网站 | 检查日期 | 备注 |
| ---- | --------- | ---------------------------------------------------------- | -------- | ---------------------------------------------------------------------------- |
| 🟢️ | KGQQ | [全民 K 歌](https://kg.qq.com/index-pc.html) | 25.09.28 | 每日签到获取鲜花 每日大约 120 鲜花左右 |
| 🟢️ | YOUDAO | [有道云笔记](https://note.youdao.com/web/) | 25.09.28 | 每日签到获取存储空间 |
| 🟢️ | TIEBA | [百度贴吧](https://tieba.baidu.com/index.html) | 25.09.28 | 贴吧每日签到 |
| 🟢️ | BAIDUWP | [百度网盘](https://pan.baidu.com/wap/svip/growth/task) | 25.09.28 | 百度网盘会员签到和答题功能 |
| 🟢️ | BILIBILI | [BiliBili](https://www.bilibili.com/) | 25.09.28 | 漫画签到,每日经验任务,自动投币,银瓜子换硬币等功能 |
| 🟢️ | V2EX | [V2EX](https://www.v2ex.com/) | 25.09.28 | 铜币奖励 |
| 🟢️ | ACFUN | [AcFun](https://www.acfun.cn/) | 25.09.28 | 每日签到香蕉 |
| 🟢️ | IQIYI | [爱奇艺](https://www.iqiyi.com/) | 25.09.28 | ① VIP7 每月免费领白金会员;② 抽白金会员 5 次;③ 摇一摇抽奖 3 次;④ 抽奖 3 次 |
| 🟢️ | SMZDM | [什么值得买](https://www.smzdm.com/) | 24.02.20 | 签到和抽奖 |
| 🟢️ | ALIYUN | [阿里云盘](https://www.aliyundrive.com/drive/) | 24.02.20 | 签到获取免费会员和空间 |
| 🟢️ | ENSHAN | [恩山无线论坛](https://www.right.com.cn/forum/) | 24.02.20 | 签到获取硬币和积分 |
| 🟢️ | FNNASCLUB | [飞牛 Nas](https://club.fnnas.com/) | 25.12.09 | 签到奖励 |
| 🟢️ | AOLAXING | [奥拉星](http://www.100bt.com/m/creditMall/?gameId=2#task) | 24.02.20 | 签到获取积分 |
| 🟢️ | IMAOTAI | i 茅台 | 25.09.28 | 申购生肖茅台 |
| 🟤 | MIMOTION | 小米运动 | 25.09.28 | 每日小米运动刷步数 |
| 🟢️ | BAIDU | [百度站点](https://ziyuan.baidu.com/site/index#/) | 25.09.28 | 提交网站页面供百度收录 |
## 💬 通知列表
- dingtalk(钉钉)
- 企业微信群机器人(企业微信)
- 企业微信应用消息(企业微信)
- telegram(TG)
- Bark(iOS)
- server 酱(微信)
- server 酱 TURBO(微信)
- pushplus(微信)
- Cool Push(QQ,微信,邮箱)
- qmsg 酱(QQ)
- 飞书(飞书)
- ntfy(安卓)
- gotify(安卓)
## 🤝 参与贡献
我们非常欢迎各种形式的贡献。如果你对贡献代码感兴趣,可以查看我们的 GitHub [Issues][github-issues-link],大展身手,向我们展示你的奇思妙想。
[![][pr-welcome-shield]][pr-welcome-link]
### 💗 感谢我们的贡献者
[![][github-contrib-shield]][github-contrib-link]
## ✨ Star 数
[![][starchart-shield]][starchart-link]
---
## 📝 License
Copyright © 2021 [Sitoi][profile-link]. <br />
This project is [MIT](https://github.com/Sitoi/dailycheckin/blob/main/LICENSE) licensed.
<!-- LINK GROUP -->
[profile-link]: https://github.com/sitoi
[github-codespace-link]: https://codespaces.new/sitoi/dailycheckin
[github-codespace-shield]: https://github.com/sitoi/dailycheckin/blob/main/images/codespaces.png?raw=true
[github-contributors-link]: https://github.com/sitoi/dailycheckin/graphs/contributors
[github-contributors-shield]: https://img.shields.io/github/contributors/sitoi/dailycheckin?color=c4f042&labelColor=black&style=flat-square
[github-forks-link]: https://github.com/sitoi/dailycheckin/network/members
[github-forks-shield]: https://img.shields.io/github/forks/sitoi/dailycheckin?color=8ae8ff&labelColor=black&style=flat-square
[github-issues-link]: https://github.com/sitoi/dailycheckin/issues
[github-issues-shield]: https://img.shields.io/github/issues/sitoi/dailycheckin?color=ff80eb&labelColor=black&style=flat-square
[github-license-link]: https://github.com/sitoi/dailycheckin/blob/main/LICENSE
[github-license-shield]: https://img.shields.io/github/license/sitoi/dailycheckin?labelColor=black&style=flat-square
[github-stars-link]: https://github.com/sitoi/dailycheckin/stargazers
[github-stars-shield]: https://img.shields.io/github/stars/sitoi/dailycheckin?color=ffcb47&labelColor=black&style=flat-square
[github-releases-link]: https://github.com/sitoi/dailycheckin/releases
[github-releases-shield]: https://img.shields.io/github/v/release/sitoi/dailycheckin?labelColor=black&style=flat-square
[github-release-date-link]: https://github.com/sitoi/dailycheckin/releases
[github-release-date-shield]: https://img.shields.io/github/release-date/sitoi/dailycheckin?labelColor=black&style=flat-square
[pr-welcome-link]: https://github.com/sitoi/dailycheckin/pulls
[pr-welcome-shield]: https://img.shields.io/badge/🤯_pr_welcome-%E2%86%92-ffcb47?labelColor=black&style=for-the-badge
[github-contrib-link]: https://github.com/sitoi/dailycheckin/graphs/contributors
[github-contrib-shield]: https://contrib.rocks/image?repo=sitoi%2Fdailycheckin
[docker-pull-shield]: https://img.shields.io/docker/pulls/sitoi/dailycheckin?labelColor=black&style=flat-square
[docker-pull-link]: https://hub.docker.com/repository/docker/sitoi/dailycheckin
[docker-size-shield]: https://img.shields.io/docker/image-size/sitoi/dailycheckin?labelColor=black&style=flat-square
[docker-size-link]: https://hub.docker.com/repository/docker/sitoi/dailycheckin
[docker-stars-shield]: https://img.shields.io/docker/stars/sitoi/dailycheckin?labelColor=black&style=flat-square
[docker-stars-link]: https://hub.docker.com/repository/docker/sitoi/dailycheckin
[pypi-dm-shield]: https://img.shields.io/pypi/dm/dailycheckin?label=pypi&labelColor=black&style=flat-square
[pypi-dm-link]: https://pypi.org/project/dailycheckin/
[python-version-link]: https://pypi.org/project/dailycheckin/
[python-version-shield]: https://img.shields.io/pypi/pyversions/dailycheckin?labelColor=black&style=flat-square
[pypi-version-shield]: https://img.shields.io/pypi/v/dailycheckin?labelColor=black&style=flat-square
[pypi-version-link]: https://pypi.org/project/dailycheckin/
[starchart-shield]: https://api.star-history.com/svg?repos=sitoi/dailycheckin&type=Date
[starchart-link]: https://star-history.com/#sitoi/dailycheckin&Date
================================================
FILE: docs/pages/install/_meta.json
================================================
{
"docker": "Docker 部署",
"qinglong": "青龙部署",
"synology": "群辉部署",
"local": "手动部署"
}
================================================
FILE: docs/pages/install/docker.mdx
================================================
import { Cards, Card } from 'nextra/components'
import { Callout } from 'nextra/components'
import { Steps } from 'nextra/components'
import { FileTree } from 'nextra/components'
<Cards>
<Card
title="手动部署"
href="/install/local"
/>
<Card
title="青龙部署"
href="/install/qinglong"
/>
<Card
title="群晖部署"
href="/install/synology"
/>
</Cards>
# Docker 使用教程
## 一、安装
运行如下命令一键启动并创建服务
```bash copy
curl https://fastly.jsdelivr.net/gh/sitoi/dailycheckin@main/docker_start.sh | bash
```
> 运行成功会自动创建如下目录结构, 并成功启动 docker 服务。
<FileTree>
<FileTree.Folder
name="."
defaultOpen
>
<FileTree.Folder
name="config"
defaultOpen
>
<FileTree.File name="config.json" />
</FileTree.Folder>
<FileTree.Folder
name="cron"
defaultOpen
>
<FileTree.File name="crontab_list.sh" />
</FileTree.Folder>
<FileTree.Folder
name="logs"
defaultOpen
>
<FileTree.File name="default_task.log" />
</FileTree.Folder>
<FileTree.File name="docker-compose.yml" />
</FileTree.Folder>
</FileTree>
- `./config/config.json`: 配置文件
- `./cron/crontab_list.sh`: 配置定时任务的文件
- `./logs`: 日志文件
- `./docker-compose.yml`: docker 启动文件(只在有 docker-compose 的情况下创建)
## 二、配置
<Callout
type="warning"
emoji="⚠️"
>
请务必到 [https://www.json.cn/](https://www.json.cn/) 网站检查 `config.json`
文件格式是否正确!
</Callout>
文件路径: `./config/config.json`
参考[配置说明文档](/settings/config) ,并修改 `config.json`
## 三、定时
修改 `./cron/crontab_list.sh` 文件, 根据实际情况修改下面的默认文件。
```bash filename="crontab_list.sh" copy
##############默认任务##############
# 每 12 小时更新 Pipy 包,如果不需要更新 pypi 包请注释掉下面这行
0 */12 * * * echo "定时任务更新依赖..." && pip install dailycheckin --upgrade --user >> /dailycheckin/logs/update-pypi.log 2>&1
# 每天的 23:50 分清理一次日志
50 23 */2 * * rm -rf /dailycheckin/logs/*.log
##############每日签到一次任务##############
# 每日签到(9:00 执行全部签到)
0 9 * * * cd /dailycheckin && dailycheckin >> /dailycheckin/logs/dailycheckin.log 2>&1
```
## 四、运行
#### 运行全部脚本
```bash copy
docker exec -it dailycheckin dailycheckin
```
#### 运行指定脚本(包含),可以同时选择多个,用「空格」分开
```bash copy
docker exec -it dailycheckin dailycheckin --include MUSIC163 BAIDU
```
#### 运行指定脚本(排除),可以同时选择多个,用「空格」分开
```bash copy
docker exec -it dailycheckin dailycheckin --exclude MUSIC163 BAIDU
```
## 更新 Pypi
```bash copy
docker exec dailycheckin sh /dailycheckin/default_task.sh
```
## 升级 Docker Image
```bash copy
curl https://fastly.jsdelivr.net/gh/sitoi/dailycheckin@main/docker_start.sh | bash
```
## 附录
### docker-compose 安装
##### 方式一(Python 环境)
```bash copy
pip3 install docker-compose
```
##### 方式二
```bash copy
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
```
通过 `docker-compose version` 查看 `docker-compose` 版本,确认是否安装成功。
### docker-compose 常用命令
- `docker-compose logs` 打印日志
- `docker-compose pull` 更新镜像
- `docker-compose stop` 停止容器
- `docker-compose restart` 重启容器
- `docker-compose down` 停止并删除容器
- `docker exec -it dailycheckin sh` 进入 docker
================================================
FILE: docs/pages/install/local.mdx
================================================
import { Cards, Card } from 'nextra/components'
import { Callout } from 'nextra/components'
<Cards>
<Card
title="Docker 部署"
href="/install/docker"
/>
<Card
title="青龙部署"
href="/install/qinglong"
/>
<Card
title="群晖部署"
href="/install/synology"
/>
</Cards>
# 手动部署
## 一、安装
```bash copy
pip install dailycheckin --user
```
## 二、配置
<Callout
type="warning"
emoji="⚠️"
>
请务必到 [https://www.json.cn/](https://www.json.cn/) 网站检查 `config.json`
文件格式是否正确!
</Callout>
在项目目录下新建并编写 `config.json` 配置文件,参考[配置说明文档](/settings/config) ,并修改 `config.json`
## 三、运行
1. 运行全部脚本
```bash copy
dailycheckin
```
2. 运行指定脚本(包含),可以同时选择多个,用「空格」分开
```bash copy
dailycheckin --include MUSIC163 BAIDU
```
3. 运行指定脚本(排除),可以同时选择多个,用「空格」分开
```bash copy
dailycheckin --exclude MUSIC163 BAIDU
```
## 四、更新
```bash copy
pip install dailycheckin --user --upgrade
```
================================================
FILE: docs/pages/install/qinglong.mdx
================================================
import { Cards, Card } from 'nextra/components'
import { Callout } from 'nextra/components'
import { Steps } from 'nextra/components'
<Cards>
<Card
title="手动部署"
href="/install/local"
/>
<Card
title="Docker 部署"
href="/install/docker"
/>
<Card
title="群晖部署"
href="/install/synology"
/>
</Cards>
# 青龙使用教程
## 一、安装
<Steps>
### 选择「依赖管理」

### 新建 Linux 依赖
#### 1. 点击 Linux

#### 2. 点击新建依赖

#### 3. 输入依赖
```text copy
gcc g++ make libffi-dev openssl-dev
```

#### 4. 点击确认,等待安装完成

### 新建 Python 依赖
#### 1. 点击 Python

#### 2. 点击新建依赖

#### 3. 输入 dailycheckin

#### 4. 点击确认,等待安装完成

</Steps>
## 二、配置
<Callout
type="warning"
emoji="⚠️"
>
请务必到 [https://www.json.cn/](https://www.json.cn/) 网站检查 `config.json`
文件格式是否正确!
</Callout>
<Steps>
### 选择「脚本管理」

### 点击 ➕ 添加

### 输入文件名 config.json 后确定

### 配置 config.json 文件
参考[配置说明文档](/settings/config) ,并修改 `config.json`


</Steps>
## 三、运行
1. 运行全部脚本

2. 运行指定脚本(包含),可以同时选择多个,用「空格」分开

3. 运行指定脚本(排除),可以同时选择多个,用「空格」分开

## 四、更新
添加一个定时任务,名称为 更新Dailycheckin(可自定义),命令为 `task pip3 install dailycheckin --upgrade`,定时规则为 0 0 * * *。
国内机器如无法完成更新,可为命令设置镜像,将命令改为 `task pip3 install dailycheckin --upgrade -i https://pypi.mirrors.ustc.edu.cn/simple/` 后再更新。

================================================
FILE: docs/pages/install/synology.mdx
================================================
import { Cards, Card } from 'nextra/components'
import { Callout } from 'nextra/components'
import { Steps } from 'nextra/components'
import { FileTree } from 'nextra/components'
<Cards>
<Card
title="手动部署"
href="/install/local"
/>
<Card
title="Docker 部署"
href="/install/docker"
/>
<Card
title="青龙部署"
href="/install/qinglong"
/>
</Cards>
# 群晖 Docker 使用教程
## 一、安装
<Steps>
### 新建项目目录
<FileTree>
<FileTree.Folder
name="dailycheckin"
defaultOpen
>
<FileTree.Folder
name="config"
defaultOpen
>
<FileTree.File name="config.json" />
</FileTree.Folder>
<FileTree.Folder
name="cron"
defaultOpen
>
<FileTree.File name="crontab_list.sh" />
</FileTree.Folder>
<FileTree.Folder
name="logs"
defaultOpen
></FileTree.Folder>
</FileTree.Folder>
</FileTree>
- `./config/config.json`: 配置文件
- `./cron/crontab_list.sh`: 配置定时任务的文件
- `./logs`: 日志文件
#### Config 目录

参考[配置说明文档](/settings/config) ,并修改 `config.json`
#### Cron 目录

修改 `./cron/crontab_list.sh` 文件, 根据实际情况修改下面的默认文件。
```bash filename="crontab_list.sh" copy
##############默认任务##############
# 每 12 小时更新 Pipy 包,如果不需要更新 pypi 包请注释掉下面这行
0 */12 * * * echo "定时任务更新依赖..." && pip install dailycheckin --upgrade --user >> /dailycheckin/logs/update-pypi.log 2>&1
# 每天的 23:50 分清理一次日志
50 23 */2 * * rm -rf /dailycheckin/logs/*.log
##############每日签到一次任务##############
# 每日签到(9:00 执行全部签到)
0 9 * * * cd /dailycheckin && dailycheckin >> /dailycheckin/logs/dailycheckin.log 2>&1
```
### 注册表搜索「dailycheckin」,双击下载

### 下载完成后,点击映像,选中「dailycheckin」,点击「启动」

### 配置网络
跳过,点击下一步

### 常规设置
☑️ 启动自动重新启动

### 端口设置
跳过,点击下一步

### 存储空间设置

##### 按照图中的文件夹添加一致的目录结构


### 容器启动成功


</Steps>
## 二、配置
<Callout
type="warning"
emoji="⚠️"
>
请务必到 [https://www.json.cn/](https://www.json.cn/) 网站检查 `config.json`
文件格式是否正确!
</Callout>
上传配置文件「config.json」到 「dailycheckin/config」目录下,参考[配置说明文档](/settings/config) ,并修改 `config.json`

## 三、运行
<Steps>
### 点击「详
gitextract_w6im42rl/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── 1_bug_report.yml │ │ └── 2_feature_request.yml │ └── workflows/ │ ├── docker-publish.yml │ ├── docs-publish.yml │ └── release-publish.yml ├── .gitignore ├── .pre-commit-config.yaml ├── LICENSE ├── Makefile ├── README.md ├── dailycheckin/ │ ├── __init__.py │ ├── __version__.py │ ├── acfun/ │ │ ├── __init__.py │ │ └── main.py │ ├── aliyun/ │ │ ├── __init__.py │ │ └── main.py │ ├── aolaxing/ │ │ ├── __init__.py │ │ └── main.py │ ├── baidu/ │ │ ├── __init__.py │ │ └── main.py │ ├── baiduwp/ │ │ ├── __init__.py │ │ └── main.py │ ├── bilibili/ │ │ ├── __init__.py │ │ └── main.py │ ├── configs.py │ ├── enshan/ │ │ ├── __init__.py │ │ └── main.py │ ├── fnnasclub/ │ │ ├── __init__.py │ │ └── main.py │ ├── imaotai/ │ │ ├── __init__.py │ │ └── main.py │ ├── iqiyi/ │ │ ├── __init__.py │ │ └── main.py │ ├── kgqq/ │ │ ├── __init__.py │ │ └── main.py │ ├── main.py │ ├── mimotion/ │ │ ├── __init__.py │ │ └── main.py │ ├── smzdm/ │ │ ├── __init__.py │ │ └── main.py │ ├── tieba/ │ │ ├── __init__.py │ │ └── main.py │ ├── utils/ │ │ ├── __init__.py │ │ └── message.py │ ├── v2ex/ │ │ ├── __init__.py │ │ └── main.py │ └── youdao/ │ ├── __init__.py │ └── main.py ├── docker/ │ ├── .dockerignore │ ├── Dockerfile │ ├── Makefile │ ├── config.template.json │ ├── crontab_list.sh │ ├── default_task.sh │ ├── docker-compose.yml │ └── start.sh ├── docker_start.sh ├── docs/ │ ├── components/ │ │ ├── CardList.tsx │ │ ├── counters.module.css │ │ └── counters.tsx │ ├── next-env.d.ts │ ├── next.config.js │ ├── package.json │ ├── pages/ │ │ ├── _meta.json │ │ ├── history.mdx │ │ ├── index.md │ │ ├── install/ │ │ │ ├── _meta.json │ │ │ ├── docker.mdx │ │ │ ├── local.mdx │ │ │ ├── qinglong.mdx │ │ │ └── synology.mdx │ │ └── settings/ │ │ ├── _meta.json │ │ ├── acfun.mdx │ │ ├── aliyun.mdx │ │ ├── aolaxing.mdx │ │ ├── baidu.mdx │ │ ├── baiduwp.mdx │ │ ├── bilibili.mdx │ │ ├── config.mdx │ │ ├── enshan.mdx │ │ ├── fnnas.mdx │ │ ├── imaotai.mdx │ │ ├── iqiyi.mdx │ │ ├── kgqq.mdx │ │ ├── mimotion.mdx │ │ ├── notify/ │ │ │ ├── _meta.json │ │ │ ├── bark.mdx │ │ │ ├── coolpush.mdx │ │ │ ├── dingtalk.mdx │ │ │ ├── feishu.mdx │ │ │ ├── gotify.mdx │ │ │ ├── ntfy.mdx │ │ │ ├── pushplus.mdx │ │ │ ├── qmsg.mdx │ │ │ ├── qywx.mdx │ │ │ ├── qywxrobot.mdx │ │ │ ├── server.mdx │ │ │ ├── telegram.mdx │ │ │ └── turbo.mdx │ │ ├── smzdm.mdx │ │ ├── tieba.mdx │ │ ├── v2ex.mdx │ │ └── youdao.mdx │ ├── theme.config.tsx │ └── tsconfig.json ├── imaotai_login.py ├── pyproject.toml ├── requirements.txt └── setup.py
SYMBOL INDEX (165 symbols across 25 files)
FILE: dailycheckin/__init__.py
class CheckIn (line 4) | class CheckIn:
FILE: dailycheckin/acfun/main.py
class AcFun (line 13) | class AcFun(CheckIn):
method __init__ (line 16) | def __init__(self, check_item: dict):
method login (line 22) | def login(phone, password, session):
method get_cookies (line 29) | def get_cookies(session, phone, password):
method get_token (line 49) | def get_token(self, session):
method get_video (line 55) | def get_video(self, session):
method sign (line 62) | def sign(session):
method danmu (line 67) | def danmu(self, session):
method throwbanana (line 92) | def throwbanana(self, session):
method like (line 99) | def like(self, session):
method share (line 113) | def share(self, session, cookies):
method get_info (line 126) | def get_info(session):
method main (line 137) | def main(self):
FILE: dailycheckin/aliyun/main.py
class AliYun (line 12) | class AliYun(CheckIn):
method __init__ (line 15) | def __init__(self, check_item: dict):
method update_token (line 18) | def update_token(self, refresh_token):
method sign (line 25) | def sign(self, access_token):
method main (line 62) | def main(self):
FILE: dailycheckin/aolaxing/main.py
class AoLaXing (line 10) | class AoLaXing(CheckIn):
method __init__ (line 13) | def __init__(self, check_item: dict):
method user (line 16) | def user(self, headers):
method practise (line 35) | def practise(self, headers, task_id):
method task (line 44) | def task(self, headers, msg: bool = False):
method main (line 67) | def main(self):
FILE: dailycheckin/baidu/main.py
class Baidu (line 10) | class Baidu(CheckIn):
method __init__ (line 13) | def __init__(self, check_item: dict):
method url_submit (line 17) | def url_submit(data_url: str, submit_url: str, times: int = 100) -> str:
method main (line 43) | def main(self):
FILE: dailycheckin/baiduwp/main.py
class BaiduWP (line 11) | class BaiduWP(CheckIn):
method __init__ (line 18) | def __init__(self, check_item: dict):
method signin (line 32) | def signin(self):
method get_question (line 48) | def get_question(self):
method answer_question (line 62) | def answer_question(self, ask_id, answer):
method get_userinfo (line 76) | def get_userinfo(self):
method main (line 90) | def main(self):
FILE: dailycheckin/bilibili/main.py
class BiliBili (line 10) | class BiliBili(CheckIn):
method __init__ (line 13) | def __init__(self, check_item: dict):
method get_nav (line 17) | def get_nav(session):
method get_today_exp (line 29) | def get_today_exp(session: requests.Session) -> list:
method vip_privilege_my (line 44) | def vip_privilege_my(session) -> dict:
method reward (line 51) | def reward(session) -> dict:
method live_sign (line 63) | def live_sign(session) -> dict:
method manga_sign (line 80) | def manga_sign(session, platform="android") -> dict:
method vip_privilege_receive (line 101) | def vip_privilege_receive(session, bili_jct, receive_type: int = 1) ->...
method vip_manga_reward (line 112) | def vip_manga_reward(session) -> dict:
method report_task (line 119) | def report_task(session, bili_jct, aid: int, cid: int, progres: int = ...
method share_task (line 132) | def share_task(session, bili_jct, aid) -> dict:
method get_followings (line 143) | def get_followings(
method space_arc_search (line 171) | def space_arc_search(
method elec_pay (line 212) | def elec_pay(session, bili_jct, uid: int, num: int = 50) -> dict:
method coin_add (line 230) | def coin_add(session, bili_jct, aid: int, num: int = 1, select_like: i...
method live_status (line 250) | def live_status(session) -> dict:
method get_region (line 266) | def get_region(session, rid=1, num=6) -> dict:
method silver2coin (line 286) | def silver2coin(session, bili_jct) -> dict:
method main (line 293) | def main(self):
FILE: dailycheckin/configs.py
function checkin_map (line 7) | def checkin_map():
function env2list (line 54) | def env2list(key):
function env2str (line 65) | def env2str(key):
function get_checkin_info (line 80) | def get_checkin_info(data):
function get_notice_info (line 91) | def get_notice_info(data):
FILE: dailycheckin/enshan/main.py
class EnShan (line 13) | class EnShan(CheckIn):
method __init__ (line 16) | def __init__(self, check_item):
method get_formhash_from_page (line 20) | def get_formhash_from_page(session):
method sign (line 38) | def sign(session, form_hash):
method get_info (line 76) | def get_info(session):
method main (line 103) | def main(self):
FILE: dailycheckin/fnnasclub/main.py
class FnNasClub (line 9) | class FnNasClub(CheckIn):
method __init__ (line 12) | def __init__(self, check_item):
method get_sign_param_from_page (line 16) | def get_sign_param_from_page(session):
method sign (line 43) | def sign(session, sign_param):
method get_info (line 88) | def get_info(session):
method main (line 148) | def main(self):
FILE: dailycheckin/imaotai/main.py
class Encrypt (line 15) | class Encrypt:
method __init__ (line 16) | def __init__(self, key, iv):
method pkcs7padding (line 20) | def pkcs7padding(self, text):
method aes_encrypt (line 31) | def aes_encrypt(self, content):
method aes_decrypt (line 39) | def aes_decrypt(self, content):
class IMAOTAI (line 47) | class IMAOTAI(CheckIn):
method __init__ (line 50) | def __init__(self, check_item):
method init_headers (line 94) | def init_headers(
method get_current_session_id (line 110) | def get_current_session_id(self):
method get_map (line 121) | def get_map(self, lat: str = "28.499562", lng: str = "102.182324"):
method max_shop (line 155) | def max_shop(self, city, item_code, p_c_map, province, shops):
method distance_shop (line 174) | def distance_shop(
method get_location_count (line 199) | def get_location_count(
method act_params (line 226) | def act_params(self, shop_id: str, item_id: str):
method reservation (line 240) | def reservation(self, params: dict):
method getUserEnergyAward (line 264) | def getUserEnergyAward(self):
method main (line 291) | def main(self):
FILE: dailycheckin/iqiyi/main.py
class IQIYI (line 13) | class IQIYI(CheckIn):
method __init__ (line 16) | def __init__(self, check_item):
method parse_cookie (line 20) | def parse_cookie(cookie):
method user_information (line 30) | def user_information(p00001):
method lottery (line 63) | def lottery(self, p00001, award_list=[]):
method draw (line 104) | def draw(draw_type, p00001, p00003):
method level_right (line 144) | def level_right(self, p00001):
method give_times (line 150) | def give_times(self, p00001):
method lotto_lottery (line 161) | def lotto_lottery(self, p00001):
method main (line 176) | def main(self):
FILE: dailycheckin/kgqq/main.py
class KGQQ (line 9) | class KGQQ(CheckIn):
method __init__ (line 12) | def __init__(self, check_item):
method sign (line 16) | def sign(kgqq_cookie):
method main (line 118) | def main(self):
FILE: dailycheckin/main.py
function parse_arguments (line 14) | def parse_arguments():
function check_config (line 21) | def check_config(task_list):
function checkin (line 66) | def checkin():
FILE: dailycheckin/mimotion/main.py
class MiMotion (line 12) | class MiMotion(CheckIn):
method __init__ (line 15) | def __init__(self, check_item):
method get_time (line 23) | def get_time(self):
method login (line 33) | def login(self, phone, password):
method main (line 69) | def main(self):
FILE: dailycheckin/smzdm/main.py
class SMZDM (line 15) | class SMZDM(CheckIn):
method __init__ (line 18) | def __init__(self, check_item: dict):
method robot_token (line 21) | def robot_token(self, headers):
method sign (line 43) | def sign(self, headers, token):
method all_reward (line 66) | def all_reward(self, headers, data):
method active (line 87) | def active(self, cookie):
method main (line 170) | def main(self):
FILE: dailycheckin/tieba/main.py
class Tieba (line 13) | class Tieba(CheckIn):
method __init__ (line 16) | def __init__(self, check_item: dict):
method request (line 52) | def request(self, url: str, method: str = "get", data: Optional[dict] ...
method encode_data (line 75) | def encode_data(self, data: dict) -> dict:
method get_user_info (line 83) | def get_user_info(self):
method get_favorite (line 98) | def get_favorite(self) -> list[dict]:
method sign_forums (line 144) | def sign_forums(self, forums, tbs: str) -> dict:
method main (line 205) | def main(self) -> str:
FILE: dailycheckin/utils/message.py
function message2server (line 12) | def message2server(sckey, content):
function message2server_turbo (line 18) | def message2server_turbo(sendkey, content):
function message2coolpush (line 30) | def message2coolpush(
function message2qmsg (line 47) | def message2qmsg(qmsg_key, qmsg_type, content):
function message2telegram (line 56) | def message2telegram(tg_api_host, tg_proxy, tg_bot_token, tg_user_id, co...
function message2feishu (line 77) | def message2feishu(fskey, content):
function message2dingtalk (line 83) | def message2dingtalk(dingtalk_secret, dingtalk_access_token, content):
function message2bark (line 99) | def message2bark(bark_url: str, content):
function message2qywxrobot (line 109) | def message2qywxrobot(qywx_key, content):
function message2qywxapp (line 117) | def message2qywxapp(
function message2pushplus (line 168) | def message2pushplus(pushplus_token, content, pushplus_topic=None):
function message2gotify (line 181) | def message2gotify(gotify_url: str, gotify_token: str, gotify_priority: ...
function message2ntfy (line 199) | def message2ntfy(ntfy_url: str, ntfy_topic: str, ntfy_priority: str, con...
function important_notice (line 224) | def important_notice():
function push_message (line 237) | def push_message(content_list: list, notice_info: dict):
FILE: dailycheckin/v2ex/main.py
class V2ex (line 13) | class V2ex(CheckIn):
method __init__ (line 16) | def __init__(self, check_item):
method sign (line 20) | def sign(session):
method main (line 69) | def main(self):
FILE: dailycheckin/youdao/main.py
class YouDao (line 9) | class YouDao(CheckIn):
method __init__ (line 12) | def __init__(self, check_item):
method sign (line 16) | def sign(cookies):
method main (line 44) | def main(self):
FILE: docs/components/CardList.tsx
type CardItem (line 4) | interface CardItem {
type CardListProps (line 11) | interface CardListProps {
function CardList (line 34) | function CardList({ cards = defaultCards }: CardListProps) {
FILE: docs/components/counters.tsx
function MyButton (line 6) | function MyButton() {
function MyApp (line 25) | function MyApp() {
FILE: docs/theme.config.tsx
method useNextSeoProps (line 66) | useNextSeoProps() {
FILE: imaotai_login.py
function init_headers (line 49) | def init_headers(user_id: str = "1", token: str = "2", lat: str = "29.83...
function select_geo (line 61) | def select_geo(i: str):
function signature (line 71) | def signature(data: dict):
function get_vcode (line 84) | def get_vcode(mobile: str):
function login (line 100) | def login(mobile: str, v_code: str):
function get_location (line 116) | def get_location():
FILE: setup.py
function read_file (line 14) | def read_file(filename):
function read_requirements (line 19) | def read_requirements(filename):
function package_files (line 41) | def package_files(directories):
Condensed preview — 109 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (278K chars).
[
{
"path": ".github/ISSUE_TEMPLATE/1_bug_report.yml",
"chars": 686,
"preview": "name: '🐛 签到失败 BUG'\ndescription: '反馈一个签到失败的 BUG'\ntitle: '[Bug] '\nlabels: ['🐛 Bug']\nbody:\n - type: dropdown\n attribute"
},
{
"path": ".github/ISSUE_TEMPLATE/2_feature_request.yml",
"chars": 475,
"preview": "name: '🌠 功能需求'\ndescription: '提出需求或建议'\ntitle: '[Request] '\nlabels: ['🌠 功能需求']\nbody:\n - type: textarea\n attributes:\n "
},
{
"path": ".github/workflows/docker-publish.yml",
"chars": 759,
"preview": "name: Docker Push\n\non:\n workflow_dispatch:\n\njobs:\n docker:\n runs-on: ubuntu-latest\n steps:\n - name: Checkou"
},
{
"path": ".github/workflows/docs-publish.yml",
"chars": 801,
"preview": "name: Deploy\n\non:\n push:\n paths:\n - 'docs/**'\ndefaults:\n run:\n shell: bash\n working-directory: ./docs\n\nj"
},
{
"path": ".github/workflows/release-publish.yml",
"chars": 1016,
"preview": "# This workflow will upload a Python Package using Twine when a release is published\n# For more information see: https:/"
},
{
"path": ".gitignore",
"chars": 1914,
"preview": "# Created by .ignore support plugin (hsz.mobi)\n### Python template\n# Byte-compiled / optimized / DLL files\n__pycache__/\n"
},
{
"path": ".pre-commit-config.yaml",
"chars": 850,
"preview": "repos:\n - repo: https://github.com/pre-commit/pre-commit-hooks\n rev: v5.0.0\n hooks:\n - id: check-added-large"
},
{
"path": "LICENSE",
"chars": 1063,
"preview": "MIT License\n\nCopyright (c) 2021 Sitoi\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof t"
},
{
"path": "Makefile",
"chars": 236,
"preview": ".PHONY: clean sdist upload pre-commit mkdocs\n\nsdist: clean\n\tpython3 setup.py sdist bdist_wheel --universa\n\nupload: clean"
},
{
"path": "README.md",
"chars": 7882,
"preview": "<div align=\"center\">\n\n<img src=\"https://socialify.git.ci/Sitoi/dailycheckin/image?font=Rokkitt&forks=1&issues=1&language"
},
{
"path": "dailycheckin/__init__.py",
"chars": 299,
"preview": "import pkgutil as _pkgutil\n\n\nclass CheckIn:\n name = \"Base\"\n\n\n__path__ = _pkgutil.extend_path(__path__, __name__)\nfor "
},
{
"path": "dailycheckin/__version__.py",
"chars": 24,
"preview": "__version__ = \"25.12.9\"\n"
},
{
"path": "dailycheckin/acfun/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/acfun/main.py",
"chars": 7233,
"preview": "import json\nimport os\nimport re\n\nimport requests\nimport urllib3\n\nfrom dailycheckin import CheckIn\n\nurllib3.disable_warni"
},
{
"path": "dailycheckin/aliyun/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/aliyun/main.py",
"chars": 2888,
"preview": "import json\nimport os\n\nimport requests\nimport urllib3\n\nfrom dailycheckin import CheckIn\n\nurllib3.disable_warnings()\n\n\ncl"
},
{
"path": "dailycheckin/aolaxing/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/aolaxing/main.py",
"chars": 3250,
"preview": "import json\nimport os\nimport time\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass AoLaXing(CheckIn):\n name"
},
{
"path": "dailycheckin/baidu/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/baidu/main.py",
"chars": 2041,
"preview": "import json\nimport os\nfrom urllib import parse\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass Baidu(CheckIn)"
},
{
"path": "dailycheckin/baiduwp/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/baiduwp/main.py",
"chars": 4048,
"preview": "import json\nimport os\nimport re\nimport time\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass BaiduWP(CheckIn):"
},
{
"path": "dailycheckin/bilibili/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/bilibili/main.py",
"chars": 15171,
"preview": "import json\nimport os\nimport time\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass BiliBili(CheckIn):\n name"
},
{
"path": "dailycheckin/configs.py",
"chars": 2202,
"preview": "import json\nimport os\n\nfrom dailycheckin import CheckIn\n\n\ndef checkin_map():\n result = {}\n for cls in CheckIn.__su"
},
{
"path": "dailycheckin/enshan/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/enshan/main.py",
"chars": 4278,
"preview": "import json\nimport os\nimport re\n\nimport requests\nimport urllib3\n\nfrom dailycheckin import CheckIn\n\nurllib3.disable_warni"
},
{
"path": "dailycheckin/fnnasclub/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/fnnasclub/main.py",
"chars": 5697,
"preview": "import json\nimport os\nimport re\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass FnNasClub(CheckIn):\n name ="
},
{
"path": "dailycheckin/imaotai/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/imaotai/main.py",
"chars": 12504,
"preview": "import base64\nimport datetime\nimport json\nimport math\nimport os\nimport random\nimport time\n\nimport requests\nfrom Crypto.C"
},
{
"path": "dailycheckin/iqiyi/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/iqiyi/main.py",
"chars": 8496,
"preview": "import json\nimport os\nimport re\nimport time\nfrom urllib.parse import unquote\nfrom uuid import uuid4\n\nimport requests\n\nfr"
},
{
"path": "dailycheckin/kgqq/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/kgqq/main.py",
"chars": 8183,
"preview": "import json\nimport os\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass KGQQ(CheckIn):\n name = \"全民K歌\"\n\n d"
},
{
"path": "dailycheckin/main.py",
"chars": 4541,
"preview": "import argparse\nimport json\nimport os\nimport time\nfrom datetime import datetime, timedelta\n\nimport requests\n\nfrom dailyc"
},
{
"path": "dailycheckin/mimotion/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/mimotion/main.py",
"chars": 20232,
"preview": "import json\nimport os\nimport random\nimport re\nimport time\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass MiM"
},
{
"path": "dailycheckin/smzdm/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/smzdm/main.py",
"chars": 6943,
"preview": "import hashlib\nimport json\nimport os\nimport re\nimport time\n\nimport requests\nimport urllib3\n\nfrom dailycheckin import Che"
},
{
"path": "dailycheckin/tieba/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/tieba/main.py",
"chars": 8714,
"preview": "import hashlib\nimport json\nimport os\nimport random\nimport time\nfrom typing import Optional\n\nimport requests\n\nfrom dailyc"
},
{
"path": "dailycheckin/utils/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/utils/message.py",
"chars": 13776,
"preview": "import base64\nimport hashlib\nimport hmac\nimport json\nimport re\nimport time\nfrom urllib.parse import quote_plus\n\nimport r"
},
{
"path": "dailycheckin/v2ex/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/v2ex/main.py",
"chars": 3632,
"preview": "import json\nimport os\nimport re\n\nimport requests\nimport urllib3\n\nfrom dailycheckin import CheckIn\n\nurllib3.disable_warni"
},
{
"path": "dailycheckin/youdao/__init__.py",
"chars": 0,
"preview": ""
},
{
"path": "dailycheckin/youdao/main.py",
"chars": 2409,
"preview": "import json\nimport os\n\nimport requests\n\nfrom dailycheckin import CheckIn\n\n\nclass YouDao(CheckIn):\n name = \"有道云笔记\"\n\n "
},
{
"path": "docker/.dockerignore",
"chars": 64,
"preview": "config.template.json\ncrontab_list.sh\nMakefile\ndocker-compose.yml"
},
{
"path": "docker/Dockerfile",
"chars": 496,
"preview": "FROM python:3.9-alpine\n\nWORKDIR /dailycheckin\nCOPY ./start.sh /usr/local/bin\n\nRUN set -ex \\\n && apk update && apk upg"
},
{
"path": "docker/Makefile",
"chars": 523,
"preview": ".PHONY: build up stop pull logs down exec buildx pushx\n\nbuildx:\n\tdocker buildx build --platform=linux/arm/v6,linux/arm/v"
},
{
"path": "docker/config.template.json",
"chars": 6739,
"preview": "{\n \"BARK_URL\": \"\",\n \"COOLPUSHEMAIL\": true,\n \"COOLPUSHQQ\": true,\n \"COOLPUSHSKEY\": \"\",\n \"COOLPUSHWX\": true,"
},
{
"path": "docker/crontab_list.sh",
"chars": 406,
"preview": "##############默认任务##############\n# 每 12 小时更新 Pipy 包,如果不需要更新 pypi 包请注释掉下面这行\n0 */12 * * * echo \"定时任务更新依赖...\" && pip instal"
},
{
"path": "docker/default_task.sh",
"chars": 216,
"preview": "#!/bin/sh\nset -e\n\nexport LANG=\"zh_CN.UTF-8\"\n\necho \"定时任务更新依赖...\"\npip install dailycheckin --upgrade --user\n\necho \"Load th"
},
{
"path": "docker/docker-compose.yml",
"chars": 268,
"preview": "version: '3'\nservices:\n dailycheckin:\n image: sitoi/dailycheckin:latest\n container_name: dailycheckin\n restart"
},
{
"path": "docker/start.sh",
"chars": 299,
"preview": "#!/bin/sh\nset -e\n\nexport LANG=\"zh_CN.UTF-8\"\n\nCRONTAB_FILE=\"/dailycheckin/cron/crontab_list.sh\"\n\necho \"安装最新依赖...\"\npip ins"
},
{
"path": "docker_start.sh",
"chars": 1492,
"preview": "#!/bin/bash\n\necho \"在当前目录下创建 config 和 cron 文件夹\"\nmkdir -p config\nmkdir -p cron\n\nCONFIG_FILE=\"config/config.json\"\nCRONTAB_F"
},
{
"path": "docs/components/CardList.tsx",
"chars": 1372,
"preview": "import { Card, Cards } from 'nextra/components'\nimport type { ReactNode } from 'react'\n\ninterface CardItem {\n title: st"
},
{
"path": "docs/components/counters.module.css",
"chars": 101,
"preview": ".counter {\n border: 1px solid #ccc;\n border-radius: 5px;\n padding: 2px 6px;\n margin: 12px 0 0;\n}\n"
},
{
"path": "docs/components/counters.tsx",
"chars": 474,
"preview": "// Example from https://beta.reactjs.org/learn\n\nimport { useState } from 'react'\nimport styles from './counters.module.c"
},
{
"path": "docs/next-env.d.ts",
"chars": 201,
"preview": "/// <reference types=\"next\" />\n/// <reference types=\"next/image-types/global\" />\n\n// NOTE: This file should not be edite"
},
{
"path": "docs/next.config.js",
"chars": 515,
"preview": "/** @type {import('next').NextConfig} */\nconst withNextra = require('nextra')({\n theme: 'nextra-theme-docs',\n themeCon"
},
{
"path": "docs/package.json",
"chars": 835,
"preview": "{\n \"name\": \"dailycheckin-docs\",\n \"version\": \"2025-09-28\",\n \"description\": \"DailyCheckIn docs\",\n \"scripts\": {\n \"de"
},
{
"path": "docs/pages/_meta.json",
"chars": 86,
"preview": "{\n \"index\": \"项目介绍\",\n \"install\": \"部署方法\",\n \"settings\": \"配置说明\",\n \"history\": \"更新日志\"\n}\n"
},
{
"path": "docs/pages/history.mdx",
"chars": 7856,
"preview": "import { Callout } from 'nextra/components'\n\n## 2025-12-09\n\n. The extraction includes 109 files (250.5 KB), approximately 87.7k tokens, and a symbol index with 165 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.