├── nb_cli_plugin_littlepaimon ├── handlers │ ├── __init__.py │ ├── gocq.py │ ├── download.py │ └── cmd.py ├── commands │ ├── __init__.py │ ├── update.py │ ├── run.py │ ├── install.py │ ├── resources.py │ └── create.py ├── plugin.py ├── __init__.py ├── meta.py ├── cli.py └── config_template.yml ├── .vscode └── settings.json ├── .pre-commit-config.yaml ├── .github └── workflows │ └── pypi-publish.yml ├── pyproject.toml ├── .gitignore ├── README.md ├── LICENSE └── poetry.lock /nb_cli_plugin_littlepaimon/handlers/__init__.py: -------------------------------------------------------------------------------- 1 | from .cmd import * 2 | from .download import ( 3 | download_json as download_json, 4 | download_with_bar as download_with_bar, 5 | ) 6 | from .gocq import download_gocq as download_gocq 7 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/commands/__init__.py: -------------------------------------------------------------------------------- 1 | from .create import create as create 2 | from .install import install as install 3 | from .resources import resources as resources 4 | from .run import run as run 5 | from .update import update as update 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "[python]": { 3 | "editor.defaultFormatter": "ms-python.black-formatter" 4 | }, 5 | "python.formatting.provider": "none", 6 | "black-formatter.args": [ 7 | "--preview" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/plugin.py: -------------------------------------------------------------------------------- 1 | from typing import cast 2 | 3 | from .cli import paimon 4 | 5 | from nb_cli.cli import cli, CLIMainGroup 6 | 7 | 8 | def main(): 9 | cli_ = cast(CLIMainGroup, cli) 10 | cli_.add_command(paimon) 11 | cli_.add_aliases("paimon", ["pm"]) 12 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | 3 | if sys.version_info < (3, 10): 4 | from importlib_metadata import version 5 | else: 6 | from importlib.metadata import version 7 | try: 8 | __version__ = version("nb-cli-plugin-littlepaimon") 9 | except Exception: 10 | __version__ = None 11 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/meta.py: -------------------------------------------------------------------------------- 1 | LOGO = """██╗ ██╗████████╗████████╗██╗ ███████╗ ██████╗ █████╗ ██╗███╗ ███╗ ██████╗ ███╗ ██╗ 2 | ██║ ██║╚══██╔══╝╚══██╔══╝██║ ██╔════╝ ██╔══██╗██╔══██╗██║████╗ ████║██╔═══██╗████╗ ██║ 3 | ██║ ██║ ██║ ██║ ██║ █████╗ ██████╔╝███████║██║██╔████╔██║██║ ██║██╔██╗ ██║ 4 | ██║ ██║ ██║ ██║ ██║ ██╔══╝ ██╔═══╝ ██╔══██║██║██║╚██╔╝██║██║ ██║██║╚██╗██║ 5 | ███████╗██║ ██║ ██║ ███████╗███████╗ ██║ ██║ ██║██║██║ ╚═╝ ██║╚██████╔╝██║ ╚████║ 6 | ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝ ╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═══╝""" # noqa: E501 7 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_install_hook_types: [pre-commit, prepare-commit-msg] 2 | ci: 3 | autofix_commit_msg: ":rotating_light: auto fix by pre-commit hooks" 4 | autofix_prs: true 5 | autoupdate_branch: master 6 | autoupdate_schedule: monthly 7 | autoupdate_commit_msg: ":arrow_up: auto update by pre-commit hooks" 8 | repos: 9 | - repo: https://github.com/psf/black 10 | rev: 23.7.0 11 | hooks: 12 | - id: black 13 | args: [--preview] 14 | stages: [commit] 15 | 16 | - repo: https://github.com/astral-sh/ruff-pre-commit 17 | rev: v0.0.280 18 | hooks: 19 | - id: ruff 20 | args: [--fix, --exit-non-zero-on-fix] 21 | stages: [commit] 22 | 23 | - repo: https://github.com/pre-commit/pre-commit-hooks 24 | rev: v4.4.0 25 | hooks: 26 | - id: end-of-file-fixer 27 | - id: trailing-whitespace 28 | -------------------------------------------------------------------------------- /.github/workflows/pypi-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build and publish to PyPI 2 | 3 | on: 4 | push: 5 | tags: 6 | - v* 7 | workflow_dispatch: 8 | 9 | jobs: 10 | build-n-publish: 11 | name: Build and publish to PyPI 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout source 16 | uses: actions/checkout@master 17 | 18 | - name: Set up Python 19 | uses: actions/setup-python@v2 20 | with: 21 | python-version: 3.8 22 | 23 | - name: Install pypa/build 24 | run: >- 25 | python -m 26 | pip install 27 | build 28 | --user 29 | - name: Build a binary wheel and a source tarball 30 | run: >- 31 | python -m 32 | build 33 | --sdist 34 | --wheel 35 | --outdir dist/ 36 | . 37 | - name: Publish distribution 📦 to PyPI 38 | uses: pypa/gh-action-pypi-publish@master 39 | with: 40 | password: ${{ secrets.PYPI_API_TOKEN }} -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/commands/update.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from pathlib import Path 3 | 4 | from ..handlers import git_pull 5 | 6 | import click 7 | from nb_cli.cli import ClickAliasedCommand, run_async 8 | from nb_cli.handlers import ( 9 | register_signal_handler, 10 | remove_signal_handler, 11 | terminate_process, 12 | ) 13 | 14 | 15 | @click.command( 16 | cls=ClickAliasedCommand, 17 | aliases=["upgrade"], 18 | help="检测更新并更新小派蒙.", 19 | ) 20 | @click.option("-d", "--cwd", default=".", help="指定工作目录.") 21 | @click.pass_context 22 | @run_async 23 | async def update(ctx: click.Context, cwd: str): 24 | if not ((Path(cwd) / "LittlePaimon").is_dir() and (Path(cwd) / "bot.py").is_file()): 25 | click.secho("未检测到当前目录下有小派蒙项目,请确保目录无误", fg="red") 26 | ctx.exit() 27 | if not (Path(cwd) / ".git").is_dir(): 28 | click.secho("未检测到当前目录下有git仓库,无法通过git更新", fg="red") 29 | ctx.exit() 30 | 31 | should_exit = asyncio.Event() 32 | 33 | def shutdown(signum, frame): 34 | should_exit.set() 35 | 36 | register_signal_handler(shutdown) 37 | 38 | async def wait_for_exit(): 39 | await should_exit.wait() 40 | await terminate_process(proc) 41 | 42 | proc = await git_pull(cwd=Path(cwd)) 43 | task = asyncio.create_task(wait_for_exit()) 44 | await proc.wait() 45 | should_exit.set() 46 | await task 47 | remove_signal_handler(shutdown) 48 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/handlers/gocq.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import platform 3 | import shutil 4 | 5 | from .download import download_with_bar 6 | 7 | from cpuinfo import get_cpu_info 8 | from nb_cli.consts import WINDOWS 9 | 10 | _SYSTEM_MAP = { 11 | "Windows": "windows", 12 | "Linux": "linux", 13 | "Darwin": "darwin", 14 | } 15 | 16 | _ARCHITECTURE_MAP = { 17 | "X86_32": "386", 18 | "X86_64": "amd64", 19 | "ARM_7": "armv7", 20 | "ARM_8": "arm64", 21 | } 22 | 23 | 24 | def _get_platform(): 25 | """ 26 | 获取系统和架构 27 | 28 | :return: 系统和架构的元组。 29 | """ 30 | try: 31 | system = _SYSTEM_MAP[platform.system()] 32 | architecture = _ARCHITECTURE_MAP[get_cpu_info()["arch"]] 33 | except KeyError: 34 | raise RuntimeError(f"Unsupported platform: {platform.uname()!r}") from None 35 | return system, architecture 36 | 37 | 38 | GOOS, GOARCH = _get_platform() 39 | 40 | ARCHIVE_EXT = ".zip" if WINDOWS else ".tar.gz" 41 | EXECUTABLE_EXT = ".exe" if WINDOWS else "" 42 | 43 | GOCQ_DIR = Path() / "go-cqhttp" 44 | 45 | 46 | def download_gocq(download_domain: str = "github.com"): 47 | """ 48 | 下载gocq 49 | 50 | :param download_domain: 下载源 51 | """ 52 | GOCQ_DIR.mkdir(parents=True, exist_ok=True) 53 | download_path = Path() / f"go-cqhttp_{GOOS}_{GOARCH}{ARCHIVE_EXT}" 54 | url = f"https://{download_domain}/Mrs4s/go-cqhttp/releases/latest/download/go-cqhttp_{GOOS}_{GOARCH}{ARCHIVE_EXT}" 55 | download_with_bar( 56 | url=url, 57 | save_path=download_path, 58 | show_name=f"go-cqhttp_{GOOS}_{GOARCH}{ARCHIVE_EXT}", 59 | ) 60 | shutil.unpack_archive(download_path, extract_dir=GOCQ_DIR) 61 | download_path.unlink() 62 | return GOCQ_DIR / f"go-cqhttp{EXECUTABLE_EXT}" 63 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/commands/run.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from pathlib import Path 3 | from typing import List, Optional 4 | 5 | from ..handlers import run_python_command 6 | 7 | import click 8 | from nb_cli.cli import ClickAliasedCommand, run_async 9 | from nb_cli.handlers import ( 10 | detect_virtualenv, 11 | register_signal_handler, 12 | remove_signal_handler, 13 | run_project, 14 | terminate_process, 15 | ) 16 | 17 | 18 | @click.command( 19 | cls=ClickAliasedCommand, 20 | aliases=["start"], 21 | context_settings={"ignore_unknown_options": True}, 22 | help="运行命令或启动小派蒙Bot.", 23 | ) 24 | @click.option("-d", "--cwd", default=".", help="指定工作目录.") 25 | @click.argument("command", nargs=-1, required=False, default=None) 26 | @click.pass_context 27 | @run_async 28 | async def run(ctx: click.Context, command: Optional[List[str]], cwd: str): 29 | if not ((Path(cwd) / "LittlePaimon").is_dir() and (Path(cwd) / "bot.py").is_file()): 30 | click.secho("未检测到该目录下有小派蒙项目,请确保目录无误", fg="red") 31 | ctx.exit() 32 | 33 | if python_path := detect_virtualenv(Path(cwd)): 34 | click.secho(f"使用虚拟环境: {python_path}", fg="green") 35 | should_exit = asyncio.Event() 36 | 37 | def shutdown(signum, frame): 38 | should_exit.set() 39 | 40 | register_signal_handler(shutdown) 41 | 42 | async def wait_for_exit(): 43 | await should_exit.wait() 44 | await terminate_process(proc) 45 | 46 | if command: 47 | proc = await run_python_command( 48 | command=command, 49 | python_path=python_path, 50 | cwd=Path(cwd), 51 | ) 52 | else: 53 | proc = await run_project(python_path=python_path, cwd=Path(cwd)) 54 | task = asyncio.create_task(wait_for_exit()) 55 | await proc.wait() 56 | should_exit.set() 57 | await task 58 | remove_signal_handler(shutdown) 59 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/commands/install.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | from typing import List, Optional 3 | 4 | from ..handlers.cmd import install_dependencies 5 | 6 | import click 7 | from nb_cli.cli import ClickAliasedCommand, run_async 8 | from nb_cli.handlers import call_pip_install, detect_virtualenv 9 | 10 | 11 | @click.command( 12 | cls=ClickAliasedCommand, 13 | aliases=["add"], 14 | context_settings={"ignore_unknown_options": True}, 15 | help="安装依赖库到小派蒙中.", 16 | ) 17 | @click.argument("name", nargs=-1, required=False, default=None) 18 | @click.option( 19 | "-f", 20 | "--file", 21 | default="requirements.txt", 22 | type=click.Path(exists=True), 23 | help="指定依赖文件的路径", 24 | ) 25 | @click.option( 26 | "-i", 27 | "--index-url", 28 | "index_url", 29 | default=None, 30 | help="pip下载所使用的镜像源", 31 | ) 32 | @click.pass_context 33 | @run_async 34 | async def install( 35 | ctx: click.Context, 36 | name: Optional[List[str]], 37 | file: Path, 38 | index_url: Optional[str], 39 | ): 40 | file_path = Path(file).absolute() 41 | if not ( 42 | (file_path.parent / "LittlePaimon").is_dir() 43 | and (file_path.parent / "bot.py").is_file() 44 | ): 45 | click.secho("未检测到当前目录下有小派蒙项目,请确保目录无误", fg="red") 46 | ctx.exit() 47 | if python_path := detect_virtualenv(file_path.parent): 48 | click.secho(f"使用虚拟环境: {python_path}", fg="green") 49 | proc = ( 50 | await call_pip_install( 51 | name, 52 | python_path=python_path, 53 | pip_args=["-i", index_url] if index_url else None, 54 | ) 55 | if name 56 | else await install_dependencies( 57 | file_path=file_path, 58 | python_path=python_path, 59 | pip_args=["-i", index_url] if index_url else None, 60 | ) 61 | ) 62 | await proc.wait() 63 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/handlers/download.py: -------------------------------------------------------------------------------- 1 | from pathlib import Path 2 | import signal 3 | from threading import Event 4 | from typing import Optional 5 | 6 | import httpx 7 | from noneprompt import CancelledError 8 | import rich.progress 9 | 10 | 11 | def download_json(url: str): 12 | """下载json文件 13 | 14 | :param url: url 15 | """ 16 | return httpx.get(url=url, verify=False).json() 17 | 18 | 19 | def download_with_bar(url: str, save_path: Path, show_name: Optional[str] = None): 20 | """ 21 | 下载文件(带进度条) 22 | 23 | :param url: url 24 | :param save_path: 保存路径 25 | :param show_name: 下载时展示的昵称 26 | """ 27 | done_event = Event() 28 | 29 | def handle_sigint(signum, frame): 30 | done_event.set() 31 | 32 | signal.signal(signal.SIGINT, handle_sigint) 33 | 34 | save_path.parent.mkdir(parents=True, exist_ok=True) 35 | with save_path.open("wb") as f: # noqa: SIM117 36 | with httpx.stream( 37 | method="GET", 38 | url=url, 39 | follow_redirects=True, 40 | verify=False, 41 | ) as datas: 42 | size = int(datas.headers["Content-Length"]) 43 | with rich.progress.Progress( 44 | rich.progress.TextColumn("[bold yellow]{task.description}"), 45 | rich.progress.BarColumn(), 46 | "[progress.percentage]{task.percentage:>3.0f}%", 47 | "•", 48 | rich.progress.DownloadColumn(), 49 | "•", 50 | rich.progress.TransferSpeedColumn(), 51 | "•", 52 | rich.progress.TimeRemainingColumn(), 53 | ) as progress: 54 | download_task = progress.add_task( 55 | show_name or save_path.name, 56 | total=size, 57 | ) 58 | for data in datas.iter_bytes(): 59 | f.write(data) 60 | progress.update(download_task, completed=datas.num_bytes_downloaded) 61 | if done_event.is_set(): 62 | raise CancelledError 63 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/cli.py: -------------------------------------------------------------------------------- 1 | from typing import cast, List 2 | 3 | from . import __version__ 4 | from .meta import LOGO 5 | 6 | import click 7 | from nb_cli import _ 8 | from nb_cli.cli import CLI_DEFAULT_STYLE, ClickAliasedGroup, run_async, run_sync 9 | from noneprompt import CancelledError, Choice, ListPrompt 10 | 11 | 12 | @click.group( 13 | cls=ClickAliasedGroup, 14 | invoke_without_command=True, 15 | help="管理 LittlePaimon.", 16 | ) 17 | @click.version_option( 18 | __version__, 19 | "-V", 20 | "--version", 21 | prog_name="paimon", 22 | message="%(prog)s: NB CLI plugin version %(version)s for LittlePaimon", 23 | ) 24 | @click.pass_context 25 | @run_async 26 | async def paimon(ctx: click.Context): 27 | """为 LittlePaimon 定制的Nonebot CLI 插件.""" 28 | if ctx.invoked_subcommand is not None: 29 | return 30 | 31 | command = cast(ClickAliasedGroup, ctx.command) 32 | 33 | # auto discover sub commands and scripts 34 | choices: List[Choice[click.Command]] = [] 35 | for sub_cmd_name in await run_sync(command.list_commands)(ctx): 36 | if sub_cmd := await run_sync(command.get_command)(ctx, sub_cmd_name): 37 | choices.append( 38 | Choice( 39 | sub_cmd.help 40 | or _("Run subcommand {sub_cmd.name!r}").format(sub_cmd=sub_cmd), 41 | sub_cmd, 42 | ), 43 | ) 44 | click.secho(LOGO, fg="green", bold=True) 45 | click.secho("欢迎来到小派蒙的Nonebot CLI 插件!", fg="green", bold=True) 46 | 47 | try: 48 | result = await ListPrompt( 49 | "你想要进行什么操作?", 50 | choices=choices, 51 | ).prompt_async(style=CLI_DEFAULT_STYLE) 52 | except CancelledError: 53 | ctx.exit() 54 | 55 | sub_cmd = result.data 56 | await run_sync(ctx.invoke)(sub_cmd) 57 | 58 | 59 | from .commands import create, install, resources, run, update 60 | 61 | paimon.add_command(create) 62 | paimon.add_command(run) 63 | paimon.add_command(install) 64 | paimon.add_command(update) 65 | paimon.add_command(resources) 66 | 67 | 68 | @paimon.command( 69 | aliases=["show"], 70 | help="展示小派蒙的LOGO.", 71 | ) 72 | def logo(): 73 | click.secho(LOGO, fg="green", bold=True) 74 | click.secho("欢迎来到小派蒙的Nonebot CLI插件!", fg="green", bold=True) 75 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/handlers/cmd.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | from pathlib import Path 3 | from typing import List, Optional 4 | 5 | from nb_cli.handlers import get_default_python 6 | 7 | 8 | async def clone_paimon(git_url: str, dir_name: str = "LittlePaimon"): 9 | """ 10 | 克隆派蒙项目 11 | 12 | :param git_url: git仓库地址 13 | :param dir_name: 要存放的文件夹名 14 | """ 15 | return await asyncio.create_subprocess_exec( 16 | "git", 17 | "clone", 18 | "--depth=1", 19 | "--single-branch", 20 | git_url, 21 | dir_name, 22 | ) 23 | 24 | 25 | async def install_dependencies( 26 | file_path: Path, 27 | python_path: Optional[str] = None, 28 | pip_args: Optional[List[str]] = None, 29 | ): 30 | """ 31 | 安装requirements.txt中的依赖 32 | 33 | :param file_path: 依赖库文件路径 34 | :param python_path: python解释器路径 35 | :param pip_args: pip参数 36 | """ 37 | if pip_args is None: 38 | pip_args = [] 39 | if python_path is None: 40 | python_path = await get_default_python() 41 | return await asyncio.create_subprocess_exec( 42 | python_path, 43 | "-m", 44 | "pip", 45 | "install", 46 | "-r", 47 | file_path.name, 48 | *pip_args, 49 | cwd=file_path.parent.absolute(), 50 | ) 51 | 52 | 53 | async def run_python_command( 54 | command: List[str], 55 | python_path: Optional[str] = None, 56 | cwd: Optional[Path] = None, 57 | ): 58 | if python_path is None: 59 | python_path = await get_default_python() 60 | return await asyncio.create_subprocess_exec( 61 | python_path, 62 | "-m", 63 | *command, 64 | cwd=cwd, 65 | ) 66 | 67 | 68 | async def check_git() -> bool: 69 | """ 70 | 检查环境变量中是否存在 git 71 | 72 | :return: 布尔值 73 | """ 74 | process = await asyncio.create_subprocess_shell( 75 | "git --version", 76 | stdout=asyncio.subprocess.PIPE, 77 | stderr=asyncio.subprocess.PIPE, 78 | ) 79 | stdout, _ = await process.communicate() 80 | return bool(stdout) 81 | 82 | 83 | async def git_pull(cwd: Optional[Path] = None): 84 | """ 85 | 通过git更新派蒙项目 86 | 87 | """ 88 | process = await asyncio.create_subprocess_shell("git pull", cwd=cwd) 89 | stdout, _ = await process.communicate() 90 | return process 91 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "nb-cli-plugin-littlepaimon" 3 | version = "1.0.3" 4 | description = "Nonebot Cli plugin for LittlePaimon" 5 | authors = ["CMHopeSunshine <277073121@qq.com>"] 6 | keywords = ["nonebot2", "nb-cli"] 7 | homepage = "https://github.com/CMHopeSunshine/nb-cli-plugin-littlepaimon" 8 | readme = "README.md" 9 | license = "AGPL" 10 | 11 | [[tool.poetry.source]] 12 | name = "aliyun" 13 | priority = "default" 14 | url = "https://mirrors.aliyun.com/pypi/simple/" 15 | 16 | 17 | [tool.poetry.dependencies] 18 | python = "^3.8" 19 | nb-cli = "^1.0.2" 20 | py-cpuinfo = "^9.0.0" 21 | rich = "^13.3.1" 22 | 23 | [tool.poetry.dev-dependencies] 24 | ruff = "^0.0.277" 25 | black = "^23.7.0" 26 | pre-commit = "^3.1.0" 27 | 28 | [tool.black] 29 | line-length = 88 30 | include = '\.pyi?$' 31 | extend-exclude = ''' 32 | ''' 33 | skip-string-normalization = true 34 | target-version = ["py38", "py39", "py310", "py311"] 35 | 36 | [tool.ruff] 37 | select = [ 38 | "E", "W", # pycodestyle 39 | "F", # pyflakes 40 | "UP", # pyupgrade 41 | "N", # pep8-naming 42 | "I", # isort 43 | "PYI", # flask8-pyi 44 | "Q", # flake8-quotes 45 | "PTH", # flake8-use-pathlib 46 | "RET", # flake8-return 47 | "RSE", # flake8-raise 48 | "T20", # flake8-print 49 | "PIE", # flake8-pie 50 | "SIM", # flake8-simplify 51 | "ISC", # flake8-implicit-str-concat 52 | "C4", # flake8-comprehensions 53 | "COM", # flake8-commas 54 | "A", # flake8-builtins 55 | "B", # flake8-bugbear 56 | "ASYNC" # flake8-async 57 | ] 58 | ignore = ["E402", "B008", "F403", "F405", "B005", "N818"] 59 | line-length = 88 60 | target-version = "py38" 61 | ignore-init-module-imports = true 62 | 63 | 64 | [tool.ruff.flake8-builtins] 65 | builtins-ignorelist = ["id", "type", "format"] 66 | 67 | [tool.ruff.isort] 68 | force-sort-within-sections = true 69 | extra-standard-library = ["typing_extensions"] 70 | force-wrap-aliases = true 71 | combine-as-imports = true 72 | order-by-type = false 73 | relative-imports-order = "closest-to-furthest" 74 | section-order = ["future", "standard-library", "first-party", "local-folder", "third-party"] 75 | 76 | [tool.ruff.pycodestyle] 77 | ignore-overlong-task-comments = true 78 | max-doc-length = 120 79 | 80 | [tool.poetry.plugins.nb] 81 | paimon = "nb_cli_plugin_littlepaimon.plugin:main" 82 | 83 | [build-system] 84 | requires = ["poetry-core>=1.0.0"] 85 | build-backend = "poetry.core.masonry.api" 86 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.toptal.com/developers/gitignore/api/python 3 | # Edit at https://www.toptal.com/developers/gitignore?templates=python 4 | 5 | ### Python ### 6 | # Byte-compiled / optimized / DLL files 7 | __pycache__/ 8 | *.py[cod] 9 | *$py.class 10 | 11 | # C extensions 12 | *.so 13 | 14 | # Distribution / packaging 15 | .Python 16 | build/ 17 | develop-eggs/ 18 | dist/ 19 | downloads/ 20 | eggs/ 21 | .eggs/ 22 | lib/ 23 | lib64/ 24 | parts/ 25 | sdist/ 26 | var/ 27 | wheels/ 28 | pip-wheel-metadata/ 29 | share/python-wheels/ 30 | *.egg-info/ 31 | .installed.cfg 32 | *.egg 33 | MANIFEST 34 | 35 | # PyInstaller 36 | # Usually these files are written by a python script from a template 37 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 38 | *.manifest 39 | *.spec 40 | 41 | # Installer logs 42 | pip-log.txt 43 | pip-delete-this-directory.txt 44 | 45 | # Unit test / coverage reports 46 | htmlcov/ 47 | .tox/ 48 | .nox/ 49 | .coverage 50 | .coverage.* 51 | .cache 52 | nosetests.xml 53 | coverage.xml 54 | *.cover 55 | *.py,cover 56 | .hypothesis/ 57 | .pytest_cache/ 58 | pytestdebug.log 59 | 60 | # Translations 61 | *.mo 62 | *.pot 63 | 64 | # Django stuff: 65 | *.log 66 | local_settings.py 67 | db.sqlite3 68 | db.sqlite3-journal 69 | 70 | # Flask stuff: 71 | instance/ 72 | .webassets-cache 73 | 74 | # Scrapy stuff: 75 | .scrapy 76 | 77 | # Sphinx documentation 78 | docs/_build/ 79 | doc/_build/ 80 | 81 | # PyBuilder 82 | target/ 83 | 84 | # Jupyter Notebook 85 | .ipynb_checkpoints 86 | 87 | # IPython 88 | profile_default/ 89 | ipython_config.py 90 | 91 | # pyenv 92 | .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 102 | __pypackages__/ 103 | 104 | # Celery stuff 105 | celerybeat-schedule 106 | celerybeat.pid 107 | 108 | # SageMath parsed files 109 | *.sage.py 110 | 111 | # Environments 112 | .venv 113 | .idea/ 114 | env/ 115 | venv/ 116 | ENV/ 117 | env.bak/ 118 | venv.bak/ 119 | 120 | # Spyder project settings 121 | .spyderproject 122 | .spyproject 123 | 124 | # Rope project settings 125 | .ropeproject 126 | 127 | # mkdocs documentation 128 | /site 129 | 130 | # mypy 131 | .mypy_cache/ 132 | .dmypy.json 133 | dmypy.json 134 | 135 | # Pyre type checker 136 | .pyre/ 137 | 138 | # pytype static type analyzer 139 | .pytype/ 140 | 141 | # End of https://www.toptal.com/developers/gitignore/api/python 142 | 143 | *.out 144 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | nonebot 4 |

5 | 6 |
7 | 8 | # NB CLI Plugin For LittlePaimon 9 | 10 | _✨ 为[小派蒙Bot](https://github.com/CMHopeSunshine/LittlePaimon)定制的 NoneBot2 CLI 插件 ✨_ 11 | 12 | 13 | license 14 | 15 | 16 | pypi 17 | 18 | python 19 | 20 | 21 |
22 | 23 | ## 演示 24 | 25 | [![asciicast](https://asciinema.org/a/kMBRbuX5lCEnk5lmXcU53ys5b.svg)](https://asciinema.org/a/kMBRbuX5lCEnk5lmXcU53ys5b) 26 | 27 | ## 安装 28 | 29 |
30 | 安装nb-cli 31 | 32 | > 请确保你的Python版本为3.8+,且在环境变量中 33 | 34 |
35 | 通过 pipx 安装 36 | 37 | ```shell 38 | pip install --user pipx 39 | pipx ensurepath 40 | pipx install nb-cli 41 | ``` 42 |
43 | 44 |
45 | 通过 pip 安装 46 | 47 | ```shell 48 | pip install nb-cli 49 | ``` 50 |
51 | 52 |
53 | 54 | --- 55 | 56 |
57 | 安装本插件 58 | 59 |
60 | 通过 nb-cli 安装 61 | 62 | ```shell 63 | nb self install nb-cli-plugin-littlepaimon 64 | ``` 65 | 66 |
67 | 68 |
69 | 通过 pipx 安装 70 | 71 | ```shell 72 | pipx inject nb-cli nb-cli-plugin-littlepaimon 73 | ``` 74 |
75 | 76 |
77 | 通过 pip 安装 78 | 79 | ```shell 80 | pip install nb-cli-plugin-littlepaimon 81 | ``` 82 |
83 | 84 |
85 | 86 | --- 87 | 88 |
89 | 安装Git 90 | 91 | ~~能上Github的话,应该都会装Git吧)~~ 92 | 93 |
94 | 95 | ## 使用 96 | 97 | - `nb paimon` 交互式使用 98 | - `nb paimon create` 99 | - 交互式指引安装[LittlePaimon](https://github.com/CMHopeSunshine/LittlePaimon) 100 | - 自动克隆源码、创建虚拟环境、安装依赖,下载并配置go-cqhttp 101 | - 添加`-g`参数,则是只下载go-cqhttp 102 | - `nb paimon run` 运行python命令或启动小派蒙 103 | - 当接有命令时,使用该目录的下python解释器运行命令,例如`nb paimon run playwright install` 104 | - 当没有命令时,使用该目录的下python解释器启动小派蒙,实际上等价于`nb run`,不过去掉了不常用的参数 105 | - `nb paimon install` 安装依赖库到小派蒙环境中 106 | - 当接有参数时,使用该目录的下pip安装依赖,例如`nb paimon install httpx` 107 | - 当没有参数时,则是使用该目录的下pip安装`requirements.txt`中的依赖 108 | - `nb paimon res` 下载或更新小派蒙的资源 109 | - `nb paimon update` 更新小派蒙,和`git pull`一样 110 | - `nb paimon logo` 展示小派蒙的logo 111 | - `nb paimon (指令) --help` 查看帮助 112 | 113 | ## TODO 114 | 115 | - [x] 更新资源 116 | - [ ] 不依赖git 117 | - [ ] 修改配置 118 | - [ ] 安装小派蒙插件 119 | - [ ] more 120 | 121 | ## 相关项目 122 | - [nb-cli](https://github.com/nonebot/nb-cli) 123 | - [LittlePaimon](https://github.com/CMHopeSunshine/LittlePaimon) -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/config_template.yml: -------------------------------------------------------------------------------- 1 | # go-cqhttp 默认配置文件 2 | 3 | account: # 账号相关 4 | uin: {{ qq }} # QQ账号 5 | password: {{ password }} # 密码为空时使用扫码登录 6 | encrypt: false # 是否开启密码加密 7 | status: 0 # 在线状态 请参考 https://docs.go-cqhttp.org/guide/config.html#在线状态 8 | relogin: # 重连设置 9 | delay: 3 # 首次重连延迟, 单位秒 10 | interval: 3 # 重连间隔 11 | max-times: 0 # 最大重连次数, 0为无限制 12 | 13 | # 是否使用服务器下发的新地址进行重连 14 | # 注意, 此设置可能导致在海外服务器上连接情况更差 15 | use-sso-address: true 16 | # 是否允许发送临时会话消息 17 | allow-temp-session: false 18 | 19 | # 数据包的签名服务器 20 | # 兼容 https://github.com/fuqiuluo/unidbg-fetch-qsign 21 | # 如果遇到 登录 45 错误, 或者发送信息风控的话需要填入一个服务器 22 | # 示例: 23 | # sign-server: 'http://127.0.0.1:8080' # 本地签名服务器 24 | # sign-server: 'https://signserver.example.com' # 线上签名服务器 25 | # 服务器可使用docker在本地搭建或者使用他人开放的服务 26 | sign-server: '-' 27 | 28 | heartbeat: 29 | # 心跳频率, 单位秒 30 | # -1 为关闭心跳 31 | interval: 5 32 | 33 | message: 34 | # 上报数据类型 35 | # 可选: string,array 36 | post-format: array 37 | # 是否忽略无效的CQ码, 如果为假将原样发送 38 | ignore-invalid-cqcode: false 39 | # 是否强制分片发送消息 40 | # 分片发送将会带来更快的速度 41 | # 但是兼容性会有些问题 42 | force-fragment: false 43 | # 是否将url分片发送 44 | fix-url: false 45 | # 下载图片等请求网络代理 46 | proxy-rewrite: '' 47 | # 是否上报自身消息 48 | report-self-message: false 49 | # 移除服务端的Reply附带的At 50 | remove-reply-at: false 51 | # 为Reply附加更多信息 52 | extra-reply-data: false 53 | # 跳过 Mime 扫描, 忽略错误数据 54 | skip-mime-scan: false 55 | # 是否自动转换 WebP 图片 56 | convert-webp-image: false 57 | # http超时时间 58 | http-timeout: 30 59 | 60 | output: 61 | # 日志等级 trace,debug,info,warn,error 62 | log-level: warn 63 | # 日志时效 单位天. 超过这个时间之前的日志将会被自动删除. 设置为 0 表示永久保留. 64 | log-aging: 15 65 | # 是否在每次启动时强制创建全新的文件储存日志. 为 false 的情况下将会在上次启动时创建的日志文件续写 66 | log-force-new: true 67 | # 是否启用日志颜色 68 | log-colorful: true 69 | # 是否启用 DEBUG 70 | debug: false # 开启调试模式 71 | 72 | # 默认中间件锚点 73 | default-middlewares: &default 74 | # 访问密钥, 强烈推荐在公网的服务器设置 75 | access-token: '' 76 | # 事件过滤器文件目录 77 | filter: '' 78 | # API限速设置 79 | # 该设置为全局生效 80 | # 原 cqhttp 虽然启用了 rate_limit 后缀, 但是基本没插件适配 81 | # 目前该限速设置为令牌桶算法, 请参考: 82 | # https://baike.baidu.com/item/%E4%BB%A4%E7%89%8C%E6%A1%B6%E7%AE%97%E6%B3%95/6597000?fr=aladdin 83 | rate-limit: 84 | enabled: false # 是否启用限速 85 | frequency: 1 # 令牌回复频率, 单位秒 86 | bucket: 1 # 令牌桶大小 87 | 88 | database: # 数据库相关设置 89 | leveldb: 90 | # 是否启用内置leveldb数据库 91 | # 启用将会增加10-20MB的内存占用和一定的磁盘空间 92 | # 关闭将无法使用 撤回 回复 get_msg 等上下文相关功能 93 | enable: true 94 | sqlite3: 95 | # 是否启用内置sqlite3数据库 96 | # 启用将会增加一定的内存占用和一定的磁盘空间 97 | # 关闭将无法使用 撤回 回复 get_msg 等上下文相关功能 98 | enable: false 99 | cachettl: 3600000000000 # 1h 100 | 101 | # 连接服务列表 102 | servers: 103 | # 添加方式,同一连接方式可添加多个,具体配置说明请查看文档 104 | # 反向WS设置 105 | - ws-reverse: 106 | # 反向WS Universal 地址 107 | universal: ws://127.0.0.1:13579/onebot/v11/ws 108 | # 重连间隔 单位毫秒 109 | reconnect-interval: 3000 110 | middlewares: 111 | <<: *default # 引用默认中间件 112 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/commands/resources.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | from pathlib import Path 3 | from typing import Optional 4 | import zipfile 5 | 6 | from ..handlers import download_json, download_with_bar 7 | 8 | import click 9 | from nb_cli.cli import CLI_DEFAULT_STYLE, ClickAliasedCommand, run_async 10 | from noneprompt import ( 11 | CancelledError, 12 | CheckboxPrompt, 13 | Choice, 14 | ConfirmPrompt, 15 | ListPrompt, 16 | ) 17 | from rich.console import Console 18 | 19 | console = Console() 20 | 21 | 22 | @click.command( 23 | cls=ClickAliasedCommand, 24 | aliases=["res"], 25 | context_settings={"ignore_unknown_options": True}, 26 | help="下载或更新小派蒙资源.", 27 | ) 28 | @click.option( 29 | "-f", 30 | "--force", 31 | default=False, 32 | is_flag=True, 33 | help="是否强制下载资源,不管是否在小派蒙目录中.", 34 | ) 35 | @click.option( 36 | "-u", 37 | "--url", 38 | "only_url", 39 | default=False, 40 | is_flag=True, 41 | help="是否只展示下载链接而不进行下载.", 42 | ) 43 | @click.pass_context 44 | @run_async 45 | async def resources( 46 | ctx: click.Context, 47 | force: Optional[bool] = False, 48 | only_url: Optional[bool] = False, 49 | ): 50 | if only_url: 51 | click.secho( 52 | "小派蒙基础必需资源:" 53 | " https://raw.githubusercontent.com/CMHopeSunshine/LittlePaimonRes/main/resources.zip", 54 | fg="yellow", 55 | ) 56 | # click.secho( 57 | # '原神数据信息: https://raw.githubusercontent.com/CMHopeSunshine/GenshinWikiMap/master/data/data.zip', 58 | # fg='yellow') 59 | click.secho( 60 | "原神图标资源:" 61 | " https://raw.githubusercontent.com/CMHopeSunshine/GenshinWikiMap/master/resources/genshin_resources.zip", 62 | fg="yellow", 63 | ) 64 | click.secho( 65 | "原神图标资源:" 66 | " https://raw.githubusercontent.com/CMHopeSunshine/GenshinWikiMap/master/resources/genshin_splash.zip", 67 | fg="yellow", 68 | ) 69 | click.secho("如有需要请自行下载!", fg="yellow") 70 | ctx.exit() 71 | cwd_path = Path() 72 | if not force and not ( 73 | (cwd_path / "LittlePaimon").is_dir() and (cwd_path / "pyproject.toml").is_file() 74 | ): 75 | click.secho("未检测到当前文件夹有小派蒙项目", fg="red") 76 | ctx.exit() 77 | try: 78 | confirm = False 79 | res_type = [] 80 | while not confirm: 81 | res_type = await CheckboxPrompt( 82 | "你要下载(更新)哪些资源?", 83 | [ 84 | Choice("小派蒙基础必需资源", "base"), 85 | # Choice('原神数据信息', 'data'), 86 | Choice("原神图标资源", "icon"), 87 | Choice("原神立绘资源", "splash"), 88 | ], 89 | default_select=[0, 1, 2], 90 | ).prompt_async(style=CLI_DEFAULT_STYLE) 91 | confirm = ( 92 | True 93 | if res_type 94 | else await ConfirmPrompt( 95 | "你还没选择任何资源", 96 | default_choice=False, 97 | ).prompt_async(style=CLI_DEFAULT_STYLE) 98 | ) 99 | if not (res_type := [res.data for res in res_type]): 100 | ctx.exit() 101 | download_url = await ListPrompt( 102 | "要使用的资源下载源?", 103 | [ 104 | Choice("github官方源(国外推荐)", ""), 105 | Choice( 106 | "cherishmoon镜像源(国内推荐)", 107 | "https://github.cherishmoon.fun/", 108 | ), 109 | Choice("ghproxy镜像源(国内备选)", "https://ghproxy.com/"), 110 | ], 111 | default_select=1, 112 | ).prompt_async(style=CLI_DEFAULT_STYLE) 113 | download_url = download_url.data 114 | if "base" in res_type: 115 | resources_path = cwd_path / "resources" 116 | resources_path.mkdir(exist_ok=True, parents=True) 117 | base_zip_path = cwd_path / "base.zip" 118 | if not force and ( 119 | (resources_path / "fonts").is_dir() 120 | and (resources_path / "LittlePaimon").is_dir() 121 | and len(list((resources_path / "LittlePaimon").rglob("*"))) >= 50 122 | ): 123 | click.secho("检测到已有部分基础资源,进行增量更新...", fg="yellow") 124 | base_resources_list = download_json( 125 | f"{download_url}https://raw.githubusercontent.com/CMHopeSunshine/LittlePaimonRes/main/resources_list.json", 126 | ) 127 | for resource in base_resources_list: 128 | file_path = resources_path / resource["path"] 129 | if file_path.exists(): 130 | if ( 131 | not resource["lock"] 132 | or hashlib.md5(file_path.read_bytes()).hexdigest() 133 | == resource["hash"] 134 | ): 135 | continue 136 | file_path.unlink() 137 | try: 138 | download_with_bar( 139 | url=f'{download_url}https://raw.githubusercontent.com/CMHopeSunshine/LittlePaimonRes/main/{resource["path"]}', 140 | save_path=file_path, 141 | show_name="基础资源" + resource["path"], 142 | ) 143 | except CancelledError as e: 144 | raise e 145 | except Exception as e: 146 | click.secho( 147 | f'下载基础资源{resource["path"]}出错: {e}', 148 | fg="red", 149 | ) 150 | else: 151 | try: 152 | download_with_bar( 153 | f"{download_url}https://raw.githubusercontent.com/CMHopeSunshine/LittlePaimonRes/main/resources.zip", 154 | base_zip_path, 155 | "小派蒙基础资源", 156 | ) 157 | with console.status("[bold yellow]解压小派蒙基础资源中..."): 158 | zipfile.ZipFile(base_zip_path).extractall( 159 | resources_path, 160 | ) 161 | except CancelledError as e: 162 | raise e 163 | except Exception as e: 164 | click.secho(f"下载小派蒙基础资源时出错: {e}", fg="red") 165 | if base_zip_path.is_file(): 166 | base_zip_path.unlink() 167 | 168 | if "data" in res_type: 169 | data_path = cwd_path / "data" / "LittlePaimon" / "genshin_data" 170 | data_path.mkdir(exist_ok=True, parents=True) 171 | data_zip_path = cwd_path / "data.zip" 172 | try: 173 | download_with_bar( 174 | f"{download_url}https://github.com/CMHopeSunshine/GenshinWikiMap/raw/master/data/data.zip", 175 | data_zip_path, 176 | "原神数据信息", 177 | ) 178 | with console.status("[bold yellow]解压原神数据资源中..."): 179 | zipfile.ZipFile(data_zip_path).extractall(data_path) 180 | except CancelledError as e: 181 | raise e 182 | except Exception as e: 183 | click.secho(f"下载原神数据信息时出错: {e}", fg="red") 184 | if data_zip_path.is_file(): 185 | data_zip_path.unlink() 186 | if "icon" in res_type: 187 | resources_path = cwd_path / "resources" / "LittlePaimon" 188 | resources_path.mkdir(exist_ok=True, parents=True) 189 | icon_zip_path = cwd_path / "icon.zip" 190 | try: 191 | download_with_bar( 192 | f"{download_url}https://github.com/CMHopeSunshine/GenshinWikiMap/raw/master/resources/genshin_resources.zip", 193 | icon_zip_path, 194 | "原神图标资源", 195 | ) 196 | with console.status("[bold yellow]解压原神图标资源中..."): 197 | zipfile.ZipFile(icon_zip_path).extractall(resources_path) 198 | except CancelledError as e: 199 | raise e 200 | except Exception as e: 201 | click.secho(f"下载原神图标资源时出错: {e}", fg="red") 202 | if icon_zip_path.is_file(): 203 | icon_zip_path.unlink() 204 | if "splash" in res_type: 205 | resources_path = cwd_path / "resources" / "LittlePaimon" / "splash" 206 | resources_path.mkdir(exist_ok=True, parents=True) 207 | splash_zip_path = cwd_path / "splash.zip" 208 | try: 209 | download_with_bar( 210 | f"{download_url}https://github.com/CMHopeSunshine/GenshinWikiMap/raw/master/resources/genshin_splash.zip", 211 | splash_zip_path, 212 | "原神立绘资源", 213 | ) 214 | with console.status("[bold yellow]解压原神立绘资源中..."): 215 | zipfile.ZipFile(splash_zip_path).extractall(resources_path) 216 | except CancelledError as e: 217 | raise e 218 | except Exception as e: 219 | click.secho(f"下载原神立绘资源时出错: {e}", fg="red") 220 | if splash_zip_path.is_file(): 221 | splash_zip_path.unlink() 222 | 223 | click.secho("资源更新完成", fg="green", bold=True) 224 | 225 | except CancelledError: 226 | ctx.exit() 227 | -------------------------------------------------------------------------------- /nb_cli_plugin_littlepaimon/commands/create.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import contextlib 3 | import os 4 | from pathlib import Path 5 | import shutil 6 | import stat 7 | from typing import Optional 8 | 9 | from ..handlers.cmd import check_git, clone_paimon, install_dependencies 10 | from ..handlers.gocq import download_gocq, EXECUTABLE_EXT 11 | 12 | import click 13 | from nb_cli.cli import CLI_DEFAULT_STYLE, ClickAliasedCommand, run_async 14 | from nb_cli.cli.commands.project import project_name_validator 15 | from nb_cli.consts import WINDOWS 16 | from nb_cli.handlers import call_pip_install, create_virtualenv 17 | from noneprompt import ( 18 | CancelledError, 19 | Choice, 20 | ConfirmPrompt, 21 | InputPrompt, 22 | ListPrompt, 23 | ) 24 | 25 | 26 | @click.command( 27 | cls=ClickAliasedCommand, 28 | aliases=["new", "init"], 29 | context_settings={"ignore_unknown_options": True}, 30 | help="在当前目录下安装小派蒙以及go-cqhttp.", 31 | ) 32 | @click.option( 33 | "-p", 34 | "--python-interpreter", 35 | default=None, 36 | help="指定Python解释器的路径", 37 | ) 38 | @click.option( 39 | "-i", 40 | "--index-url", 41 | "index_url", 42 | default=None, 43 | help="pip下载所使用的镜像源", 44 | ) 45 | @click.option( 46 | "-q", 47 | "--only-gocq", 48 | "only_gocq", 49 | default=False, 50 | is_flag=True, 51 | help="是否只下载go-cqhttp本体", 52 | ) 53 | @click.pass_context 54 | @run_async 55 | async def create( 56 | ctx: click.Context, 57 | python_interpreter: Optional[str], 58 | index_url: Optional[str], 59 | only_gocq: bool = False, 60 | ): 61 | """在当前目录下安装小派蒙以及go-cqhttp.""" 62 | click.clear() 63 | if only_gocq: 64 | with contextlib.suppress(CancelledError): 65 | gocq_download_domain = await ListPrompt( 66 | "要使用的go-cqhttp下载源?", 67 | [ 68 | Choice("Github官方源(国外推荐)", "github.com"), 69 | Choice("FastGit镜像源(国内推荐)", "download.fgit.cf"), 70 | ], 71 | default_select=1, 72 | ).prompt_async(style=CLI_DEFAULT_STYLE) 73 | gocq_path = None 74 | try: 75 | click.secho("下载go-cqhttp中...", fg="yellow") 76 | gocq_path = download_gocq(gocq_download_domain.data) 77 | except CancelledError as e: 78 | raise e 79 | except Exception as e: 80 | click.secho(f"下载go-cqhttp失败: {e}", fg="red") 81 | if gocq_path and gocq_path.exists(): 82 | bot_qq = await InputPrompt( 83 | "机器人的QQ号:", 84 | validator=lambda x: x.isdigit(), 85 | ).prompt_async(style=CLI_DEFAULT_STYLE) 86 | password = await InputPrompt( 87 | "机器人的密码(留空则为扫码登录):", 88 | is_password=True, 89 | ).prompt_async(style=CLI_DEFAULT_STYLE) 90 | config_data = ( 91 | (Path(__file__).parent.parent / "config_template.yml") 92 | .read_text(encoding="utf-8") 93 | .replace("{{ qq }}", bot_qq) 94 | .replace("{{ password }}", password) 95 | ) 96 | (Path() / "go-cqhttp" / "config.yml").write_text( 97 | config_data, 98 | encoding="utf-8", 99 | ) 100 | click.secho("go-cqhttp下载并配置完成") 101 | else: 102 | click.secho("go-cqhttp下载失败, 请稍后手动安装", fg="red") 103 | ctx.exit() 104 | 105 | click.secho("检查前置环境...", fg="yellow") 106 | if not await check_git(): 107 | click.secho("[Git]未安装,请先自行安装Git", fg="red") 108 | ctx.exit() 109 | else: 110 | click.secho("开始安装小派蒙...", fg="yellow") 111 | try: 112 | is_clone = False 113 | while True: 114 | # 项目名称 115 | project_name = await InputPrompt( 116 | "项目名称:", 117 | default_text="LittlePaimon", 118 | validator=project_name_validator, 119 | ).prompt_async(style=CLI_DEFAULT_STYLE) 120 | project_name = project_name.replace(" ", "-") 121 | 122 | # 检查项目是否存在 123 | if (Path() / project_name).is_dir(): 124 | dir_choice = await ListPrompt( 125 | "当前目录下已存在同名项目文件夹,如何操作?", 126 | [ 127 | Choice("删除该文件夹并重新克隆", "delete"), 128 | Choice("使用该文件夹中的内容并继续", "use"), 129 | Choice("重新命名", "rename"), 130 | Choice("取消安装", "exit"), 131 | ], 132 | default_select=0, 133 | ).prompt_async(style=CLI_DEFAULT_STYLE) 134 | if dir_choice.data == "rename": 135 | pass 136 | elif dir_choice.data == "delete": 137 | 138 | def delete(func, path_, execinfo): 139 | os.chmod(path_, stat.S_IWUSR) # noqa: PTH101 140 | func(path_) 141 | 142 | shutil.rmtree( 143 | (Path() / project_name).absolute(), 144 | onerror=delete, 145 | ) 146 | await asyncio.sleep(0.2) 147 | break 148 | elif dir_choice.data == "use": 149 | is_clone = True 150 | break 151 | else: 152 | ctx.exit() 153 | else: 154 | break 155 | 156 | if not is_clone: 157 | git_url = await ListPrompt( 158 | "要使用的克隆源?", 159 | [ 160 | Choice( 161 | "github官方源(国外推荐)", 162 | "https://github.com/CMHopeSunshine/LittlePaimon", 163 | ), 164 | Choice( 165 | "cherishmoon镜像源(国内推荐)", 166 | "https://github.cherishmoon.fun/https://github.com/CMHopeSunshine/LittlePaimon", 167 | ), 168 | Choice( 169 | "ghproxy镜像源(国内备选1)", 170 | "https://ghproxy.com/https://github.com/CMHopeSunshine/LittlePaimon", 171 | ), 172 | Choice( 173 | "gitee镜像源(国内备选2)", 174 | "https://gitee.com/cherishmoon/LittlePaimon", 175 | ), 176 | ], 177 | default_select=1, 178 | ).prompt_async(style=CLI_DEFAULT_STYLE) 179 | click.secho(f"在 {project_name} 文件夹克隆源码...", fg="yellow") 180 | clone_result = await clone_paimon(git_url.data, project_name) 181 | await clone_result.wait() 182 | 183 | if not (Path() / project_name / ".env.prod").is_file(): 184 | ctx.exit() 185 | 186 | env_file = (Path() / project_name / ".env.prod").read_text( 187 | encoding="utf-8", 188 | ) 189 | superusers = await InputPrompt( 190 | "超级用户QQ(即你自己的QQ号,多个用空格隔开):", 191 | validator=lambda x: x.replace(" ", "").isdigit(), 192 | ).prompt_async(style=CLI_DEFAULT_STYLE) 193 | if superusers := superusers.replace(" ", '", "'): 194 | env_file = env_file.replace( 195 | 'SUPERUSERS=["123456"]', 196 | f'SUPERUSERS=["{superusers}"]', 197 | ) 198 | (Path() / project_name / ".env.prod").write_text( 199 | env_file, 200 | encoding="utf-8", 201 | ) 202 | 203 | is_install_dependencies = await ConfirmPrompt( 204 | "立刻安装依赖?", 205 | default_choice=True, 206 | ).prompt_async(style=CLI_DEFAULT_STYLE) 207 | venv_dir = Path() / project_name / ".venv" 208 | 209 | python_path = None 210 | if is_install_dependencies: 211 | is_use_venv = await ConfirmPrompt( 212 | "创建虚拟环境?", 213 | default_choice=True, 214 | ).prompt_async(style=CLI_DEFAULT_STYLE) 215 | 216 | python_path = None 217 | if is_use_venv: 218 | click.secho( 219 | f"在 {venv_dir} 中创建虚拟环境...", 220 | fg="yellow", 221 | ) 222 | await create_virtualenv( 223 | venv_dir, 224 | prompt=project_name, 225 | python_path=python_interpreter, 226 | ) 227 | python_path = str( 228 | ( 229 | venv_dir 230 | / ("Scripts" if WINDOWS else "bin") 231 | / ("python.exe" if WINDOWS else "python") 232 | ).absolute(), 233 | ) 234 | 235 | click.secho("开始安装相关依赖...", fg="yellow") 236 | proc = await install_dependencies( 237 | file_path=Path() / project_name / "requirements.txt", 238 | python_path=python_path, 239 | pip_args=["-i", index_url] if index_url else None, 240 | ) 241 | await proc.wait() 242 | 243 | if not (Path() / project_name).is_dir(): 244 | ctx.exit() 245 | 246 | # go-cqhttp 247 | gocq_type = 0 248 | if (Path() / "go-cqhttp" / f"go-cqhttp{EXECUTABLE_EXT}").exists(): 249 | click.secho( 250 | "检测到当前目录下已有go-cqhttp本体,跳过安装go-cqhttp", 251 | fg="yellow", 252 | ) 253 | else: 254 | install_gocq_type = await ListPrompt( 255 | "go-cqhttp安装和使用方式?", 256 | [ 257 | Choice("nonebot-plugin-gocqhttp插件", "plugin"), 258 | Choice("go-cqhttp本体", "gocq"), 259 | Choice("我已安装或稍候自行安装", "skip"), 260 | ], 261 | default_select=0, 262 | ).prompt_async(style=CLI_DEFAULT_STYLE) 263 | 264 | if install_gocq_type.data == "plugin": 265 | gocq_type = 1 266 | proc = await call_pip_install( 267 | "nonebot-plugin-gocqhttp", 268 | python_path=python_path, 269 | ) 270 | await proc.wait() 271 | toml_file = (Path() / project_name / "pyproject.toml").read_text( 272 | encoding="utf-8", 273 | ) 274 | toml_file = toml_file.replace( 275 | "plugins = []", 276 | 'plugins = ["nonebot_plugin_gocqhttp"]', 277 | ) 278 | (Path() / project_name / "pyproject.toml").write_text( 279 | toml_file, 280 | encoding="utf-8", 281 | ) 282 | elif install_gocq_type.data == "gocq": 283 | gocq_download_domain = await ListPrompt( 284 | "要使用的go-cqhttp下载源?", 285 | [ 286 | Choice("Github官方源(国外推荐)", "github.com"), 287 | Choice("FastGit镜像源(国内推荐)", "download.fgit.ml"), 288 | ], 289 | default_select=1, 290 | ).prompt_async(style=CLI_DEFAULT_STYLE) 291 | gocq_path = None 292 | try: 293 | click.secho("下载go-cqhttp中...", fg="yellow") 294 | gocq_path = download_gocq(gocq_download_domain.data) 295 | except CancelledError as e: 296 | raise e 297 | except Exception as e: 298 | click.secho(f"下载go-cqhttp失败: {e}", fg="red") 299 | if gocq_path and gocq_path.exists(): 300 | gocq_type = 2 301 | bot_qq = await InputPrompt( 302 | "机器人的QQ号:", 303 | validator=lambda x: x.isdigit(), 304 | ).prompt_async(style=CLI_DEFAULT_STYLE) 305 | password = await InputPrompt( 306 | "机器人的密码(留空则为扫码登录):", 307 | is_password=True, 308 | ).prompt_async(style=CLI_DEFAULT_STYLE) 309 | config_data = ( 310 | (Path(__file__).parent.parent / "config_template.yml") 311 | .read_text(encoding="utf-8") 312 | .replace("{{ qq }}", bot_qq) 313 | .replace("{{ password }}", password) 314 | ) 315 | (Path() / "go-cqhttp" / "config.yml").write_text( 316 | config_data, 317 | encoding="utf-8", 318 | ) 319 | else: 320 | click.secho("go-cqhttp安装失败, 请稍后手动安装", fg="red") 321 | click.secho("安装完成!", fg="green") 322 | click.secho("运行以下命令来启动你的小派蒙:", fg="green") 323 | if gocq_type == 2: 324 | if WINDOWS: 325 | click.secho(f" cd {project_name}", fg="green") 326 | click.secho(" nb paimon run", fg="green") 327 | click.secho(" 双击运行go-cqhttp文件夹下的go-cqhttp.exe", fg="green") 328 | click.secho(" 两个窗口都不能关闭!!!", fg="green") 329 | else: 330 | click.secho(" cd go-cqhttp", fg="green") 331 | click.secho(" chmod 755 go-cqhttp (仅首次需要)", fg="green") 332 | click.secho(" nohup ./go-cqhttp &", fg="green") 333 | click.secho(f" cd ../{project_name}", fg="green") 334 | click.secho(" nb paimon run", fg="green") 335 | else: 336 | click.secho(f" cd {project_name}", fg="green") 337 | if not is_install_dependencies: 338 | click.secho(" 使用你自己的依赖管理器来安装依赖", fg="green") 339 | click.secho(" nb paimon run", fg="green") 340 | if gocq_type == 1: 341 | click.secho(" 访问http://127.0.0.1:13579/go-cqhttp登录账号") 342 | click.secho("开始享用小派蒙吧!", fg="green") 343 | 344 | except CancelledError: 345 | ctx.exit() 346 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU AFFERO GENERAL PUBLIC LICENSE 2 | Version 3, 19 November 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | Preamble 9 | 10 | The GNU Affero General Public License is a free, copyleft license for 11 | software and other kinds of works, specifically designed to ensure 12 | cooperation with the community in the case of network server software. 13 | 14 | The licenses for most software and other practical works are designed 15 | to take away your freedom to share and change the works. By contrast, 16 | our General Public Licenses are intended to guarantee your freedom to 17 | share and change all versions of a program--to make sure it remains free 18 | software for all its users. 19 | 20 | When we speak of free software, we are referring to freedom, not 21 | price. Our General Public Licenses are designed to make sure that you 22 | have the freedom to distribute copies of free software (and charge for 23 | them if you wish), that you receive source code or can get it if you 24 | want it, that you can change the software or use pieces of it in new 25 | free programs, and that you know you can do these things. 26 | 27 | Developers that use our General Public Licenses protect your rights 28 | with two steps: (1) assert copyright on the software, and (2) offer 29 | you this License which gives you legal permission to copy, distribute 30 | and/or modify the software. 31 | 32 | A secondary benefit of defending all users' freedom is that 33 | improvements made in alternate versions of the program, if they 34 | receive widespread use, become available for other developers to 35 | incorporate. Many developers of free software are heartened and 36 | encouraged by the resulting cooperation. However, in the case of 37 | software used on network servers, this result may fail to come about. 38 | The GNU General Public License permits making a modified version and 39 | letting the public access it on a server without ever releasing its 40 | source code to the public. 41 | 42 | The GNU Affero General Public License is designed specifically to 43 | ensure that, in such cases, the modified source code becomes available 44 | to the community. It requires the operator of a network server to 45 | provide the source code of the modified version running there to the 46 | users of that server. Therefore, public use of a modified version, on 47 | a publicly accessible server, gives the public access to the source 48 | code of the modified version. 49 | 50 | An older license, called the Affero General Public License and 51 | published by Affero, was designed to accomplish similar goals. This is 52 | a different license, not a version of the Affero GPL, but Affero has 53 | released a new version of the Affero GPL which permits relicensing under 54 | this license. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | TERMS AND CONDITIONS 60 | 61 | 0. Definitions. 62 | 63 | "This License" refers to version 3 of the GNU Affero General Public License. 64 | 65 | "Copyright" also means copyright-like laws that apply to other kinds of 66 | works, such as semiconductor masks. 67 | 68 | "The Program" refers to any copyrightable work licensed under this 69 | License. Each licensee is addressed as "you". "Licensees" and 70 | "recipients" may be individuals or organizations. 71 | 72 | To "modify" a work means to copy from or adapt all or part of the work 73 | in a fashion requiring copyright permission, other than the making of an 74 | exact copy. The resulting work is called a "modified version" of the 75 | earlier work or a work "based on" the earlier work. 76 | 77 | A "covered work" means either the unmodified Program or a work based 78 | on the Program. 79 | 80 | To "propagate" a work means to do anything with it that, without 81 | permission, would make you directly or secondarily liable for 82 | infringement under applicable copyright law, except executing it on a 83 | computer or modifying a private copy. Propagation includes copying, 84 | distribution (with or without modification), making available to the 85 | public, and in some countries other activities as well. 86 | 87 | To "convey" a work means any kind of propagation that enables other 88 | parties to make or receive copies. Mere interaction with a user through 89 | a computer network, with no transfer of a copy, is not conveying. 90 | 91 | An interactive user interface displays "Appropriate Legal Notices" 92 | to the extent that it includes a convenient and prominently visible 93 | feature that (1) displays an appropriate copyright notice, and (2) 94 | tells the user that there is no warranty for the work (except to the 95 | extent that warranties are provided), that licensees may convey the 96 | work under this License, and how to view a copy of this License. If 97 | the interface presents a list of user commands or options, such as a 98 | menu, a prominent item in the list meets this criterion. 99 | 100 | 1. Source Code. 101 | 102 | The "source code" for a work means the preferred form of the work 103 | for making modifications to it. "Object code" means any non-source 104 | form of a work. 105 | 106 | A "Standard Interface" means an interface that either is an official 107 | standard defined by a recognized standards body, or, in the case of 108 | interfaces specified for a particular programming language, one that 109 | is widely used among developers working in that language. 110 | 111 | The "System Libraries" of an executable work include anything, other 112 | than the work as a whole, that (a) is included in the normal form of 113 | packaging a Major Component, but which is not part of that Major 114 | Component, and (b) serves only to enable use of the work with that 115 | Major Component, or to implement a Standard Interface for which an 116 | implementation is available to the public in source code form. A 117 | "Major Component", in this context, means a major essential component 118 | (kernel, window system, and so on) of the specific operating system 119 | (if any) on which the executable work runs, or a compiler used to 120 | produce the work, or an object code interpreter used to run it. 121 | 122 | The "Corresponding Source" for a work in object code form means all 123 | the source code needed to generate, install, and (for an executable 124 | work) run the object code and to modify the work, including scripts to 125 | control those activities. However, it does not include the work's 126 | System Libraries, or general-purpose tools or generally available free 127 | programs which are used unmodified in performing those activities but 128 | which are not part of the work. For example, Corresponding Source 129 | includes interface definition files associated with source files for 130 | the work, and the source code for shared libraries and dynamically 131 | linked subprograms that the work is specifically designed to require, 132 | such as by intimate data communication or control flow between those 133 | subprograms and other parts of the work. 134 | 135 | The Corresponding Source need not include anything that users 136 | can regenerate automatically from other parts of the Corresponding 137 | Source. 138 | 139 | The Corresponding Source for a work in source code form is that 140 | same work. 141 | 142 | 2. Basic Permissions. 143 | 144 | All rights granted under this License are granted for the term of 145 | copyright on the Program, and are irrevocable provided the stated 146 | conditions are met. This License explicitly affirms your unlimited 147 | permission to run the unmodified Program. The output from running a 148 | covered work is covered by this License only if the output, given its 149 | content, constitutes a covered work. This License acknowledges your 150 | rights of fair use or other equivalent, as provided by copyright law. 151 | 152 | You may make, run and propagate covered works that you do not 153 | convey, without conditions so long as your license otherwise remains 154 | in force. You may convey covered works to others for the sole purpose 155 | of having them make modifications exclusively for you, or provide you 156 | with facilities for running those works, provided that you comply with 157 | the terms of this License in conveying all material for which you do 158 | not control copyright. Those thus making or running the covered works 159 | for you must do so exclusively on your behalf, under your direction 160 | and control, on terms that prohibit them from making any copies of 161 | your copyrighted material outside their relationship with you. 162 | 163 | Conveying under any other circumstances is permitted solely under 164 | the conditions stated below. Sublicensing is not allowed; section 10 165 | makes it unnecessary. 166 | 167 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law. 168 | 169 | No covered work shall be deemed part of an effective technological 170 | measure under any applicable law fulfilling obligations under article 171 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or 172 | similar laws prohibiting or restricting circumvention of such 173 | measures. 174 | 175 | When you convey a covered work, you waive any legal power to forbid 176 | circumvention of technological measures to the extent such circumvention 177 | is effected by exercising rights under this License with respect to 178 | the covered work, and you disclaim any intention to limit operation or 179 | modification of the work as a means of enforcing, against the work's 180 | users, your or third parties' legal rights to forbid circumvention of 181 | technological measures. 182 | 183 | 4. Conveying Verbatim Copies. 184 | 185 | You may convey verbatim copies of the Program's source code as you 186 | receive it, in any medium, provided that you conspicuously and 187 | appropriately publish on each copy an appropriate copyright notice; 188 | keep intact all notices stating that this License and any 189 | non-permissive terms added in accord with section 7 apply to the code; 190 | keep intact all notices of the absence of any warranty; and give all 191 | recipients a copy of this License along with the Program. 192 | 193 | You may charge any price or no price for each copy that you convey, 194 | and you may offer support or warranty protection for a fee. 195 | 196 | 5. Conveying Modified Source Versions. 197 | 198 | You may convey a work based on the Program, or the modifications to 199 | produce it from the Program, in the form of source code under the 200 | terms of section 4, provided that you also meet all of these conditions: 201 | 202 | a) The work must carry prominent notices stating that you modified 203 | it, and giving a relevant date. 204 | 205 | b) The work must carry prominent notices stating that it is 206 | released under this License and any conditions added under section 207 | 7. This requirement modifies the requirement in section 4 to 208 | "keep intact all notices". 209 | 210 | c) You must license the entire work, as a whole, under this 211 | License to anyone who comes into possession of a copy. This 212 | License will therefore apply, along with any applicable section 7 213 | additional terms, to the whole of the work, and all its parts, 214 | regardless of how they are packaged. This License gives no 215 | permission to license the work in any other way, but it does not 216 | invalidate such permission if you have separately received it. 217 | 218 | d) If the work has interactive user interfaces, each must display 219 | Appropriate Legal Notices; however, if the Program has interactive 220 | interfaces that do not display Appropriate Legal Notices, your 221 | work need not make them do so. 222 | 223 | A compilation of a covered work with other separate and independent 224 | works, which are not by their nature extensions of the covered work, 225 | and which are not combined with it such as to form a larger program, 226 | in or on a volume of a storage or distribution medium, is called an 227 | "aggregate" if the compilation and its resulting copyright are not 228 | used to limit the access or legal rights of the compilation's users 229 | beyond what the individual works permit. Inclusion of a covered work 230 | in an aggregate does not cause this License to apply to the other 231 | parts of the aggregate. 232 | 233 | 6. Conveying Non-Source Forms. 234 | 235 | You may convey a covered work in object code form under the terms 236 | of sections 4 and 5, provided that you also convey the 237 | machine-readable Corresponding Source under the terms of this License, 238 | in one of these ways: 239 | 240 | a) Convey the object code in, or embodied in, a physical product 241 | (including a physical distribution medium), accompanied by the 242 | Corresponding Source fixed on a durable physical medium 243 | customarily used for software interchange. 244 | 245 | b) Convey the object code in, or embodied in, a physical product 246 | (including a physical distribution medium), accompanied by a 247 | written offer, valid for at least three years and valid for as 248 | long as you offer spare parts or customer support for that product 249 | model, to give anyone who possesses the object code either (1) a 250 | copy of the Corresponding Source for all the software in the 251 | product that is covered by this License, on a durable physical 252 | medium customarily used for software interchange, for a price no 253 | more than your reasonable cost of physically performing this 254 | conveying of source, or (2) access to copy the 255 | Corresponding Source from a network server at no charge. 256 | 257 | c) Convey individual copies of the object code with a copy of the 258 | written offer to provide the Corresponding Source. This 259 | alternative is allowed only occasionally and noncommercially, and 260 | only if you received the object code with such an offer, in accord 261 | with subsection 6b. 262 | 263 | d) Convey the object code by offering access from a designated 264 | place (gratis or for a charge), and offer equivalent access to the 265 | Corresponding Source in the same way through the same place at no 266 | further charge. You need not require recipients to copy the 267 | Corresponding Source along with the object code. If the place to 268 | copy the object code is a network server, the Corresponding Source 269 | may be on a different server (operated by you or a third party) 270 | that supports equivalent copying facilities, provided you maintain 271 | clear directions next to the object code saying where to find the 272 | Corresponding Source. Regardless of what server hosts the 273 | Corresponding Source, you remain obligated to ensure that it is 274 | available for as long as needed to satisfy these requirements. 275 | 276 | e) Convey the object code using peer-to-peer transmission, provided 277 | you inform other peers where the object code and Corresponding 278 | Source of the work are being offered to the general public at no 279 | charge under subsection 6d. 280 | 281 | A separable portion of the object code, whose source code is excluded 282 | from the Corresponding Source as a System Library, need not be 283 | included in conveying the object code work. 284 | 285 | A "User Product" is either (1) a "consumer product", which means any 286 | tangible personal property which is normally used for personal, family, 287 | or household purposes, or (2) anything designed or sold for incorporation 288 | into a dwelling. In determining whether a product is a consumer product, 289 | doubtful cases shall be resolved in favor of coverage. For a particular 290 | product received by a particular user, "normally used" refers to a 291 | typical or common use of that class of product, regardless of the status 292 | of the particular user or of the way in which the particular user 293 | actually uses, or expects or is expected to use, the product. A product 294 | is a consumer product regardless of whether the product has substantial 295 | commercial, industrial or non-consumer uses, unless such uses represent 296 | the only significant mode of use of the product. 297 | 298 | "Installation Information" for a User Product means any methods, 299 | procedures, authorization keys, or other information required to install 300 | and execute modified versions of a covered work in that User Product from 301 | a modified version of its Corresponding Source. The information must 302 | suffice to ensure that the continued functioning of the modified object 303 | code is in no case prevented or interfered with solely because 304 | modification has been made. 305 | 306 | If you convey an object code work under this section in, or with, or 307 | specifically for use in, a User Product, and the conveying occurs as 308 | part of a transaction in which the right of possession and use of the 309 | User Product is transferred to the recipient in perpetuity or for a 310 | fixed term (regardless of how the transaction is characterized), the 311 | Corresponding Source conveyed under this section must be accompanied 312 | by the Installation Information. But this requirement does not apply 313 | if neither you nor any third party retains the ability to install 314 | modified object code on the User Product (for example, the work has 315 | been installed in ROM). 316 | 317 | The requirement to provide Installation Information does not include a 318 | requirement to continue to provide support service, warranty, or updates 319 | for a work that has been modified or installed by the recipient, or for 320 | the User Product in which it has been modified or installed. Access to a 321 | network may be denied when the modification itself materially and 322 | adversely affects the operation of the network or violates the rules and 323 | protocols for communication across the network. 324 | 325 | Corresponding Source conveyed, and Installation Information provided, 326 | in accord with this section must be in a format that is publicly 327 | documented (and with an implementation available to the public in 328 | source code form), and must require no special password or key for 329 | unpacking, reading or copying. 330 | 331 | 7. Additional Terms. 332 | 333 | "Additional permissions" are terms that supplement the terms of this 334 | License by making exceptions from one or more of its conditions. 335 | Additional permissions that are applicable to the entire Program shall 336 | be treated as though they were included in this License, to the extent 337 | that they are valid under applicable law. If additional permissions 338 | apply only to part of the Program, that part may be used separately 339 | under those permissions, but the entire Program remains governed by 340 | this License without regard to the additional permissions. 341 | 342 | When you convey a copy of a covered work, you may at your option 343 | remove any additional permissions from that copy, or from any part of 344 | it. (Additional permissions may be written to require their own 345 | removal in certain cases when you modify the work.) You may place 346 | additional permissions on material, added by you to a covered work, 347 | for which you have or can give appropriate copyright permission. 348 | 349 | Notwithstanding any other provision of this License, for material you 350 | add to a covered work, you may (if authorized by the copyright holders of 351 | that material) supplement the terms of this License with terms: 352 | 353 | a) Disclaiming warranty or limiting liability differently from the 354 | terms of sections 15 and 16 of this License; or 355 | 356 | b) Requiring preservation of specified reasonable legal notices or 357 | author attributions in that material or in the Appropriate Legal 358 | Notices displayed by works containing it; or 359 | 360 | c) Prohibiting misrepresentation of the origin of that material, or 361 | requiring that modified versions of such material be marked in 362 | reasonable ways as different from the original version; or 363 | 364 | d) Limiting the use for publicity purposes of names of licensors or 365 | authors of the material; or 366 | 367 | e) Declining to grant rights under trademark law for use of some 368 | trade names, trademarks, or service marks; or 369 | 370 | f) Requiring indemnification of licensors and authors of that 371 | material by anyone who conveys the material (or modified versions of 372 | it) with contractual assumptions of liability to the recipient, for 373 | any liability that these contractual assumptions directly impose on 374 | those licensors and authors. 375 | 376 | All other non-permissive additional terms are considered "further 377 | restrictions" within the meaning of section 10. If the Program as you 378 | received it, or any part of it, contains a notice stating that it is 379 | governed by this License along with a term that is a further 380 | restriction, you may remove that term. If a license document contains 381 | a further restriction but permits relicensing or conveying under this 382 | License, you may add to a covered work material governed by the terms 383 | of that license document, provided that the further restriction does 384 | not survive such relicensing or conveying. 385 | 386 | If you add terms to a covered work in accord with this section, you 387 | must place, in the relevant source files, a statement of the 388 | additional terms that apply to those files, or a notice indicating 389 | where to find the applicable terms. 390 | 391 | Additional terms, permissive or non-permissive, may be stated in the 392 | form of a separately written license, or stated as exceptions; 393 | the above requirements apply either way. 394 | 395 | 8. Termination. 396 | 397 | You may not propagate or modify a covered work except as expressly 398 | provided under this License. Any attempt otherwise to propagate or 399 | modify it is void, and will automatically terminate your rights under 400 | this License (including any patent licenses granted under the third 401 | paragraph of section 11). 402 | 403 | However, if you cease all violation of this License, then your 404 | license from a particular copyright holder is reinstated (a) 405 | provisionally, unless and until the copyright holder explicitly and 406 | finally terminates your license, and (b) permanently, if the copyright 407 | holder fails to notify you of the violation by some reasonable means 408 | prior to 60 days after the cessation. 409 | 410 | Moreover, your license from a particular copyright holder is 411 | reinstated permanently if the copyright holder notifies you of the 412 | violation by some reasonable means, this is the first time you have 413 | received notice of violation of this License (for any work) from that 414 | copyright holder, and you cure the violation prior to 30 days after 415 | your receipt of the notice. 416 | 417 | Termination of your rights under this section does not terminate the 418 | licenses of parties who have received copies or rights from you under 419 | this License. If your rights have been terminated and not permanently 420 | reinstated, you do not qualify to receive new licenses for the same 421 | material under section 10. 422 | 423 | 9. Acceptance Not Required for Having Copies. 424 | 425 | You are not required to accept this License in order to receive or 426 | run a copy of the Program. Ancillary propagation of a covered work 427 | occurring solely as a consequence of using peer-to-peer transmission 428 | to receive a copy likewise does not require acceptance. However, 429 | nothing other than this License grants you permission to propagate or 430 | modify any covered work. These actions infringe copyright if you do 431 | not accept this License. Therefore, by modifying or propagating a 432 | covered work, you indicate your acceptance of this License to do so. 433 | 434 | 10. Automatic Licensing of Downstream Recipients. 435 | 436 | Each time you convey a covered work, the recipient automatically 437 | receives a license from the original licensors, to run, modify and 438 | propagate that work, subject to this License. You are not responsible 439 | for enforcing compliance by third parties with this License. 440 | 441 | An "entity transaction" is a transaction transferring control of an 442 | organization, or substantially all assets of one, or subdividing an 443 | organization, or merging organizations. If propagation of a covered 444 | work results from an entity transaction, each party to that 445 | transaction who receives a copy of the work also receives whatever 446 | licenses to the work the party's predecessor in interest had or could 447 | give under the previous paragraph, plus a right to possession of the 448 | Corresponding Source of the work from the predecessor in interest, if 449 | the predecessor has it or can get it with reasonable efforts. 450 | 451 | You may not impose any further restrictions on the exercise of the 452 | rights granted or affirmed under this License. For example, you may 453 | not impose a license fee, royalty, or other charge for exercise of 454 | rights granted under this License, and you may not initiate litigation 455 | (including a cross-claim or counterclaim in a lawsuit) alleging that 456 | any patent claim is infringed by making, using, selling, offering for 457 | sale, or importing the Program or any portion of it. 458 | 459 | 11. Patents. 460 | 461 | A "contributor" is a copyright holder who authorizes use under this 462 | License of the Program or a work on which the Program is based. The 463 | work thus licensed is called the contributor's "contributor version". 464 | 465 | A contributor's "essential patent claims" are all patent claims 466 | owned or controlled by the contributor, whether already acquired or 467 | hereafter acquired, that would be infringed by some manner, permitted 468 | by this License, of making, using, or selling its contributor version, 469 | but do not include claims that would be infringed only as a 470 | consequence of further modification of the contributor version. For 471 | purposes of this definition, "control" includes the right to grant 472 | patent sublicenses in a manner consistent with the requirements of 473 | this License. 474 | 475 | Each contributor grants you a non-exclusive, worldwide, royalty-free 476 | patent license under the contributor's essential patent claims, to 477 | make, use, sell, offer for sale, import and otherwise run, modify and 478 | propagate the contents of its contributor version. 479 | 480 | In the following three paragraphs, a "patent license" is any express 481 | agreement or commitment, however denominated, not to enforce a patent 482 | (such as an express permission to practice a patent or covenant not to 483 | sue for patent infringement). To "grant" such a patent license to a 484 | party means to make such an agreement or commitment not to enforce a 485 | patent against the party. 486 | 487 | If you convey a covered work, knowingly relying on a patent license, 488 | and the Corresponding Source of the work is not available for anyone 489 | to copy, free of charge and under the terms of this License, through a 490 | publicly available network server or other readily accessible means, 491 | then you must either (1) cause the Corresponding Source to be so 492 | available, or (2) arrange to deprive yourself of the benefit of the 493 | patent license for this particular work, or (3) arrange, in a manner 494 | consistent with the requirements of this License, to extend the patent 495 | license to downstream recipients. "Knowingly relying" means you have 496 | actual knowledge that, but for the patent license, your conveying the 497 | covered work in a country, or your recipient's use of the covered work 498 | in a country, would infringe one or more identifiable patents in that 499 | country that you have reason to believe are valid. 500 | 501 | If, pursuant to or in connection with a single transaction or 502 | arrangement, you convey, or propagate by procuring conveyance of, a 503 | covered work, and grant a patent license to some of the parties 504 | receiving the covered work authorizing them to use, propagate, modify 505 | or convey a specific copy of the covered work, then the patent license 506 | you grant is automatically extended to all recipients of the covered 507 | work and works based on it. 508 | 509 | A patent license is "discriminatory" if it does not include within 510 | the scope of its coverage, prohibits the exercise of, or is 511 | conditioned on the non-exercise of one or more of the rights that are 512 | specifically granted under this License. You may not convey a covered 513 | work if you are a party to an arrangement with a third party that is 514 | in the business of distributing software, under which you make payment 515 | to the third party based on the extent of your activity of conveying 516 | the work, and under which the third party grants, to any of the 517 | parties who would receive the covered work from you, a discriminatory 518 | patent license (a) in connection with copies of the covered work 519 | conveyed by you (or copies made from those copies), or (b) primarily 520 | for and in connection with specific products or compilations that 521 | contain the covered work, unless you entered into that arrangement, 522 | or that patent license was granted, prior to 28 March 2007. 523 | 524 | Nothing in this License shall be construed as excluding or limiting 525 | any implied license or other defenses to infringement that may 526 | otherwise be available to you under applicable patent law. 527 | 528 | 12. No Surrender of Others' Freedom. 529 | 530 | If conditions are imposed on you (whether by court order, agreement or 531 | otherwise) that contradict the conditions of this License, they do not 532 | excuse you from the conditions of this License. If you cannot convey a 533 | covered work so as to satisfy simultaneously your obligations under this 534 | License and any other pertinent obligations, then as a consequence you may 535 | not convey it at all. For example, if you agree to terms that obligate you 536 | to collect a royalty for further conveying from those to whom you convey 537 | the Program, the only way you could satisfy both those terms and this 538 | License would be to refrain entirely from conveying the Program. 539 | 540 | 13. Remote Network Interaction; Use with the GNU General Public License. 541 | 542 | Notwithstanding any other provision of this License, if you modify the 543 | Program, your modified version must prominently offer all users 544 | interacting with it remotely through a computer network (if your version 545 | supports such interaction) an opportunity to receive the Corresponding 546 | Source of your version by providing access to the Corresponding Source 547 | from a network server at no charge, through some standard or customary 548 | means of facilitating copying of software. This Corresponding Source 549 | shall include the Corresponding Source for any work covered by version 3 550 | of the GNU General Public License that is incorporated pursuant to the 551 | following paragraph. 552 | 553 | Notwithstanding any other provision of this License, you have 554 | permission to link or combine any covered work with a work licensed 555 | under version 3 of the GNU General Public License into a single 556 | combined work, and to convey the resulting work. The terms of this 557 | License will continue to apply to the part which is the covered work, 558 | but the work with which it is combined will remain governed by version 559 | 3 of the GNU General Public License. 560 | 561 | 14. Revised Versions of this License. 562 | 563 | The Free Software Foundation may publish revised and/or new versions of 564 | the GNU Affero General Public License from time to time. Such new versions 565 | will be similar in spirit to the present version, but may differ in detail to 566 | address new problems or concerns. 567 | 568 | Each version is given a distinguishing version number. If the 569 | Program specifies that a certain numbered version of the GNU Affero General 570 | Public License "or any later version" applies to it, you have the 571 | option of following the terms and conditions either of that numbered 572 | version or of any later version published by the Free Software 573 | Foundation. If the Program does not specify a version number of the 574 | GNU Affero General Public License, you may choose any version ever published 575 | by the Free Software Foundation. 576 | 577 | If the Program specifies that a proxy can decide which future 578 | versions of the GNU Affero General Public License can be used, that proxy's 579 | public statement of acceptance of a version permanently authorizes you 580 | to choose that version for the Program. 581 | 582 | Later license versions may give you additional or different 583 | permissions. However, no additional obligations are imposed on any 584 | author or copyright holder as a result of your choosing to follow a 585 | later version. 586 | 587 | 15. Disclaimer of Warranty. 588 | 589 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY 590 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT 591 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY 592 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, 593 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 594 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM 595 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF 596 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 597 | 598 | 16. Limitation of Liability. 599 | 600 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 601 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 602 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY 603 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE 604 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF 605 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD 606 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), 607 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF 608 | SUCH DAMAGES. 609 | 610 | 17. Interpretation of Sections 15 and 16. 611 | 612 | If the disclaimer of warranty and limitation of liability provided 613 | above cannot be given local legal effect according to their terms, 614 | reviewing courts shall apply local law that most closely approximates 615 | an absolute waiver of all civil liability in connection with the 616 | Program, unless a warranty or assumption of liability accompanies a 617 | copy of the Program in return for a fee. 618 | 619 | END OF TERMS AND CONDITIONS 620 | 621 | How to Apply These Terms to Your New Programs 622 | 623 | If you develop a new program, and you want it to be of the greatest 624 | possible use to the public, the best way to achieve this is to make it 625 | free software which everyone can redistribute and change under these terms. 626 | 627 | To do so, attach the following notices to the program. It is safest 628 | to attach them to the start of each source file to most effectively 629 | state the exclusion of warranty; and each file should have at least 630 | the "copyright" line and a pointer to where the full notice is found. 631 | 632 | 633 | Copyright (C) 634 | 635 | This program is free software: you can redistribute it and/or modify 636 | it under the terms of the GNU Affero General Public License as published 637 | by the Free Software Foundation, either version 3 of the License, or 638 | (at your option) any later version. 639 | 640 | This program is distributed in the hope that it will be useful, 641 | but WITHOUT ANY WARRANTY; without even the implied warranty of 642 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 643 | GNU Affero General Public License for more details. 644 | 645 | You should have received a copy of the GNU Affero General Public License 646 | along with this program. If not, see . 647 | 648 | Also add information on how to contact you by electronic and paper mail. 649 | 650 | If your software can interact with users remotely through a computer 651 | network, you should also make sure that it provides a way for users to 652 | get its source. For example, if your program is a web application, its 653 | interface could display a "Source" link that leads users to an archive 654 | of the code. There are many ways you could offer source, and different 655 | solutions will be better for different programs; see section 13 for the 656 | specific requirements. 657 | 658 | You should also get your employer (if you work as a programmer) or school, 659 | if any, to sign a "copyright disclaimer" for the program, if necessary. 660 | For more information on this, and how to apply and follow the GNU AGPL, see 661 | . 662 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "anyio" 5 | version = "3.7.1" 6 | description = "High level compatibility layer for multiple asynchronous event loop implementations" 7 | optional = false 8 | python-versions = ">=3.7" 9 | files = [ 10 | {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, 11 | {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, 12 | ] 13 | 14 | [package.dependencies] 15 | exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} 16 | idna = ">=2.8" 17 | sniffio = ">=1.1" 18 | 19 | [package.extras] 20 | doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] 21 | test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] 22 | trio = ["trio (<0.22)"] 23 | 24 | [package.source] 25 | type = "legacy" 26 | url = "https://mirrors.aliyun.com/pypi/simple" 27 | reference = "aliyun" 28 | 29 | [[package]] 30 | name = "arrow" 31 | version = "1.2.3" 32 | description = "Better dates & times for Python" 33 | optional = false 34 | python-versions = ">=3.6" 35 | files = [ 36 | {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, 37 | {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, 38 | ] 39 | 40 | [package.dependencies] 41 | python-dateutil = ">=2.7.0" 42 | 43 | [package.source] 44 | type = "legacy" 45 | url = "https://mirrors.aliyun.com/pypi/simple" 46 | reference = "aliyun" 47 | 48 | [[package]] 49 | name = "binaryornot" 50 | version = "0.4.4" 51 | description = "Ultra-lightweight pure Python package to check if a file is binary or text." 52 | optional = false 53 | python-versions = "*" 54 | files = [ 55 | {file = "binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4"}, 56 | {file = "binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061"}, 57 | ] 58 | 59 | [package.dependencies] 60 | chardet = ">=3.0.2" 61 | 62 | [package.source] 63 | type = "legacy" 64 | url = "https://mirrors.aliyun.com/pypi/simple" 65 | reference = "aliyun" 66 | 67 | [[package]] 68 | name = "black" 69 | version = "23.7.0" 70 | description = "The uncompromising code formatter." 71 | optional = false 72 | python-versions = ">=3.8" 73 | files = [ 74 | {file = "black-23.7.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:5c4bc552ab52f6c1c506ccae05681fab58c3f72d59ae6e6639e8885e94fe2587"}, 75 | {file = "black-23.7.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:552513d5cd5694590d7ef6f46e1767a4df9af168d449ff767b13b084c020e63f"}, 76 | {file = "black-23.7.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:86cee259349b4448adb4ef9b204bb4467aae74a386bce85d56ba4f5dc0da27be"}, 77 | {file = "black-23.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:501387a9edcb75d7ae8a4412bb8749900386eaef258f1aefab18adddea1936bc"}, 78 | {file = "black-23.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb074d8b213749fa1d077d630db0d5f8cc3b2ae63587ad4116e8a436e9bbe995"}, 79 | {file = "black-23.7.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b5b0ee6d96b345a8b420100b7d71ebfdd19fab5e8301aff48ec270042cd40ac2"}, 80 | {file = "black-23.7.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:893695a76b140881531062d48476ebe4a48f5d1e9388177e175d76234ca247cd"}, 81 | {file = "black-23.7.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:c333286dc3ddca6fdff74670b911cccedacb4ef0a60b34e491b8a67c833b343a"}, 82 | {file = "black-23.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831d8f54c3a8c8cf55f64d0422ee875eecac26f5f649fb6c1df65316b67c8926"}, 83 | {file = "black-23.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:7f3bf2dec7d541b4619b8ce526bda74a6b0bffc480a163fed32eb8b3c9aed8ad"}, 84 | {file = "black-23.7.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:f9062af71c59c004cd519e2fb8f5d25d39e46d3af011b41ab43b9c74e27e236f"}, 85 | {file = "black-23.7.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:01ede61aac8c154b55f35301fac3e730baf0c9cf8120f65a9cd61a81cfb4a0c3"}, 86 | {file = "black-23.7.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:327a8c2550ddc573b51e2c352adb88143464bb9d92c10416feb86b0f5aee5ff6"}, 87 | {file = "black-23.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1c6022b86f83b632d06f2b02774134def5d4d4f1dac8bef16d90cda18ba28a"}, 88 | {file = "black-23.7.0-cp38-cp38-win_amd64.whl", hash = "sha256:27eb7a0c71604d5de083757fbdb245b1a4fae60e9596514c6ec497eb63f95320"}, 89 | {file = "black-23.7.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:8417dbd2f57b5701492cd46edcecc4f9208dc75529bcf76c514864e48da867d9"}, 90 | {file = "black-23.7.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:47e56d83aad53ca140da0af87678fb38e44fd6bc0af71eebab2d1f59b1acf1d3"}, 91 | {file = "black-23.7.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:25cc308838fe71f7065df53aedd20327969d05671bac95b38fdf37ebe70ac087"}, 92 | {file = "black-23.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:642496b675095d423f9b8448243336f8ec71c9d4d57ec17bf795b67f08132a91"}, 93 | {file = "black-23.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:ad0014efc7acf0bd745792bd0d8857413652979200ab924fbf239062adc12491"}, 94 | {file = "black-23.7.0-py3-none-any.whl", hash = "sha256:9fd59d418c60c0348505f2ddf9609c1e1de8e7493eab96198fc89d9f865e7a96"}, 95 | {file = "black-23.7.0.tar.gz", hash = "sha256:022a582720b0d9480ed82576c920a8c1dde97cc38ff11d8d8859b3bd6ca9eedb"}, 96 | ] 97 | 98 | [package.dependencies] 99 | click = ">=8.0.0" 100 | mypy-extensions = ">=0.4.3" 101 | packaging = ">=22.0" 102 | pathspec = ">=0.9.0" 103 | platformdirs = ">=2" 104 | tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} 105 | typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} 106 | 107 | [package.extras] 108 | colorama = ["colorama (>=0.4.3)"] 109 | d = ["aiohttp (>=3.7.4)"] 110 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 111 | uvloop = ["uvloop (>=0.15.2)"] 112 | 113 | [package.source] 114 | type = "legacy" 115 | url = "https://mirrors.aliyun.com/pypi/simple" 116 | reference = "aliyun" 117 | 118 | [[package]] 119 | name = "cashews" 120 | version = "6.2.0" 121 | description = "cache tools with async power" 122 | optional = false 123 | python-versions = ">=3.7" 124 | files = [ 125 | {file = "cashews-6.2.0-py3-none-any.whl", hash = "sha256:8a005fdb429efad8a99e2d8c3024a0a59bed35d49fe67da35a2cd9cb1d56cd89"}, 126 | {file = "cashews-6.2.0.tar.gz", hash = "sha256:c197202336d1bfde732bf43c30c8fd3fdb5836700e8a81bdd25abcc5ea1df9c8"}, 127 | ] 128 | 129 | [package.extras] 130 | dill = ["dill"] 131 | diskcache = ["diskcache (>=5.0.0)"] 132 | redis = ["redis (>=4.3.1)"] 133 | speedup = ["bitarray (<3.0.0)", "hiredis", "xxhash (<4.0.0)"] 134 | tests = ["hypothesis", "pytest", "pytest-asyncio"] 135 | 136 | [package.source] 137 | type = "legacy" 138 | url = "https://mirrors.aliyun.com/pypi/simple" 139 | reference = "aliyun" 140 | 141 | [[package]] 142 | name = "certifi" 143 | version = "2023.7.22" 144 | description = "Python package for providing Mozilla's CA Bundle." 145 | optional = false 146 | python-versions = ">=3.6" 147 | files = [ 148 | {file = "certifi-2023.7.22-py3-none-any.whl", hash = "sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9"}, 149 | {file = "certifi-2023.7.22.tar.gz", hash = "sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082"}, 150 | ] 151 | 152 | [package.source] 153 | type = "legacy" 154 | url = "https://mirrors.aliyun.com/pypi/simple" 155 | reference = "aliyun" 156 | 157 | [[package]] 158 | name = "cfgv" 159 | version = "3.3.1" 160 | description = "Validate configuration and produce human readable error messages." 161 | optional = false 162 | python-versions = ">=3.6.1" 163 | files = [ 164 | {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, 165 | {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, 166 | ] 167 | 168 | [package.source] 169 | type = "legacy" 170 | url = "https://mirrors.aliyun.com/pypi/simple" 171 | reference = "aliyun" 172 | 173 | [[package]] 174 | name = "chardet" 175 | version = "5.1.0" 176 | description = "Universal encoding detector for Python 3" 177 | optional = false 178 | python-versions = ">=3.7" 179 | files = [ 180 | {file = "chardet-5.1.0-py3-none-any.whl", hash = "sha256:362777fb014af596ad31334fde1e8c327dfdb076e1960d1694662d46a6917ab9"}, 181 | {file = "chardet-5.1.0.tar.gz", hash = "sha256:0d62712b956bc154f85fb0a266e2a3c5913c2967e00348701b32411d6def31e5"}, 182 | ] 183 | 184 | [package.source] 185 | type = "legacy" 186 | url = "https://mirrors.aliyun.com/pypi/simple" 187 | reference = "aliyun" 188 | 189 | [[package]] 190 | name = "charset-normalizer" 191 | version = "3.2.0" 192 | description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." 193 | optional = false 194 | python-versions = ">=3.7.0" 195 | files = [ 196 | {file = "charset-normalizer-3.2.0.tar.gz", hash = "sha256:3bb3d25a8e6c0aedd251753a79ae98a093c7e7b471faa3aa9a93a81431987ace"}, 197 | {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b87549028f680ca955556e3bd57013ab47474c3124dc069faa0b6545b6c9710"}, 198 | {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7c70087bfee18a42b4040bb9ec1ca15a08242cf5867c58726530bdf3945672ed"}, 199 | {file = "charset_normalizer-3.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a103b3a7069b62f5d4890ae1b8f0597618f628b286b03d4bc9195230b154bfa9"}, 200 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94aea8eff76ee6d1cdacb07dd2123a68283cb5569e0250feab1240058f53b623"}, 201 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db901e2ac34c931d73054d9797383d0f8009991e723dab15109740a63e7f902a"}, 202 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b0dac0ff919ba34d4df1b6131f59ce95b08b9065233446be7e459f95554c0dc8"}, 203 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:193cbc708ea3aca45e7221ae58f0fd63f933753a9bfb498a3b474878f12caaad"}, 204 | {file = "charset_normalizer-3.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09393e1b2a9461950b1c9a45d5fd251dc7c6f228acab64da1c9c0165d9c7765c"}, 205 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:baacc6aee0b2ef6f3d308e197b5d7a81c0e70b06beae1f1fcacffdbd124fe0e3"}, 206 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bf420121d4c8dce6b889f0e8e4ec0ca34b7f40186203f06a946fa0276ba54029"}, 207 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c04a46716adde8d927adb9457bbe39cf473e1e2c2f5d0a16ceb837e5d841ad4f"}, 208 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:aaf63899c94de41fe3cf934601b0f7ccb6b428c6e4eeb80da72c58eab077b19a"}, 209 | {file = "charset_normalizer-3.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62e51710986674142526ab9f78663ca2b0726066ae26b78b22e0f5e571238dd"}, 210 | {file = "charset_normalizer-3.2.0-cp310-cp310-win32.whl", hash = "sha256:04e57ab9fbf9607b77f7d057974694b4f6b142da9ed4a199859d9d4d5c63fe96"}, 211 | {file = "charset_normalizer-3.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:48021783bdf96e3d6de03a6e39a1171ed5bd7e8bb93fc84cc649d11490f87cea"}, 212 | {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4957669ef390f0e6719db3613ab3a7631e68424604a7b448f079bee145da6e09"}, 213 | {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:46fb8c61d794b78ec7134a715a3e564aafc8f6b5e338417cb19fe9f57a5a9bf2"}, 214 | {file = "charset_normalizer-3.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f779d3ad205f108d14e99bb3859aa7dd8e9c68874617c72354d7ecaec2a054ac"}, 215 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f25c229a6ba38a35ae6e25ca1264621cc25d4d38dca2942a7fce0b67a4efe918"}, 216 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2efb1bd13885392adfda4614c33d3b68dee4921fd0ac1d3988f8cbb7d589e72a"}, 217 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f30b48dd7fa1474554b0b0f3fdfdd4c13b5c737a3c6284d3cdc424ec0ffff3a"}, 218 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:246de67b99b6851627d945db38147d1b209a899311b1305dd84916f2b88526c6"}, 219 | {file = "charset_normalizer-3.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bd9b3b31adcb054116447ea22caa61a285d92e94d710aa5ec97992ff5eb7cf3"}, 220 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8c2f5e83493748286002f9369f3e6607c565a6a90425a3a1fef5ae32a36d749d"}, 221 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3170c9399da12c9dc66366e9d14da8bf7147e1e9d9ea566067bbce7bb74bd9c2"}, 222 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7a4826ad2bd6b07ca615c74ab91f32f6c96d08f6fcc3902ceeedaec8cdc3bcd6"}, 223 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:3b1613dd5aee995ec6d4c69f00378bbd07614702a315a2cf6c1d21461fe17c23"}, 224 | {file = "charset_normalizer-3.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9e608aafdb55eb9f255034709e20d5a83b6d60c054df0802fa9c9883d0a937aa"}, 225 | {file = "charset_normalizer-3.2.0-cp311-cp311-win32.whl", hash = "sha256:f2a1d0fd4242bd8643ce6f98927cf9c04540af6efa92323e9d3124f57727bfc1"}, 226 | {file = "charset_normalizer-3.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:681eb3d7e02e3c3655d1b16059fbfb605ac464c834a0c629048a30fad2b27489"}, 227 | {file = "charset_normalizer-3.2.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c57921cda3a80d0f2b8aec7e25c8aa14479ea92b5b51b6876d975d925a2ea346"}, 228 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41b25eaa7d15909cf3ac4c96088c1f266a9a93ec44f87f1d13d4a0e86c81b982"}, 229 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f058f6963fd82eb143c692cecdc89e075fa0828db2e5b291070485390b2f1c9c"}, 230 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7647ebdfb9682b7bb97e2a5e7cb6ae735b1c25008a70b906aecca294ee96cf4"}, 231 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eef9df1eefada2c09a5e7a40991b9fc6ac6ef20b1372abd48d2794a316dc0449"}, 232 | {file = "charset_normalizer-3.2.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e03b8895a6990c9ab2cdcd0f2fe44088ca1c65ae592b8f795c3294af00a461c3"}, 233 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ee4006268ed33370957f55bf2e6f4d263eaf4dc3cfc473d1d90baff6ed36ce4a"}, 234 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c4983bf937209c57240cff65906b18bb35e64ae872da6a0db937d7b4af845dd7"}, 235 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:3bb7fda7260735efe66d5107fb7e6af6a7c04c7fce9b2514e04b7a74b06bf5dd"}, 236 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:72814c01533f51d68702802d74f77ea026b5ec52793c791e2da806a3844a46c3"}, 237 | {file = "charset_normalizer-3.2.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70c610f6cbe4b9fce272c407dd9d07e33e6bf7b4aa1b7ffb6f6ded8e634e3592"}, 238 | {file = "charset_normalizer-3.2.0-cp37-cp37m-win32.whl", hash = "sha256:a401b4598e5d3f4a9a811f3daf42ee2291790c7f9d74b18d75d6e21dda98a1a1"}, 239 | {file = "charset_normalizer-3.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c0b21078a4b56965e2b12f247467b234734491897e99c1d51cee628da9786959"}, 240 | {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:95eb302ff792e12aba9a8b8f8474ab229a83c103d74a750ec0bd1c1eea32e669"}, 241 | {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1a100c6d595a7f316f1b6f01d20815d916e75ff98c27a01ae817439ea7726329"}, 242 | {file = "charset_normalizer-3.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6339d047dab2780cc6220f46306628e04d9750f02f983ddb37439ca47ced7149"}, 243 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4b749b9cc6ee664a3300bb3a273c1ca8068c46be705b6c31cf5d276f8628a94"}, 244 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38856a971c602f98472050165cea2cdc97709240373041b69030be15047691f"}, 245 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f87f746ee241d30d6ed93969de31e5ffd09a2961a051e60ae6bddde9ec3583aa"}, 246 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f1b185a01fe560bc8ae5f619e924407efca2191b56ce749ec84982fc59a32a"}, 247 | {file = "charset_normalizer-3.2.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1c8a2f4c69e08e89632defbfabec2feb8a8d99edc9f89ce33c4b9e36ab63037"}, 248 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2f4ac36d8e2b4cc1aa71df3dd84ff8efbe3bfb97ac41242fbcfc053c67434f46"}, 249 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a386ebe437176aab38c041de1260cd3ea459c6ce5263594399880bbc398225b2"}, 250 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ccd16eb18a849fd8dcb23e23380e2f0a354e8daa0c984b8a732d9cfaba3a776d"}, 251 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6a5bf2cba5ae1bb80b154ed68a3cfa2fa00fde979a7f50d6598d3e17d9ac20c"}, 252 | {file = "charset_normalizer-3.2.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45de3f87179c1823e6d9e32156fb14c1927fcc9aba21433f088fdfb555b77c10"}, 253 | {file = "charset_normalizer-3.2.0-cp38-cp38-win32.whl", hash = "sha256:1000fba1057b92a65daec275aec30586c3de2401ccdcd41f8a5c1e2c87078706"}, 254 | {file = "charset_normalizer-3.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:8b2c760cfc7042b27ebdb4a43a4453bd829a5742503599144d54a032c5dc7e9e"}, 255 | {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:855eafa5d5a2034b4621c74925d89c5efef61418570e5ef9b37717d9c796419c"}, 256 | {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:203f0c8871d5a7987be20c72442488a0b8cfd0f43b7973771640fc593f56321f"}, 257 | {file = "charset_normalizer-3.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e857a2232ba53ae940d3456f7533ce6ca98b81917d47adc3c7fd55dad8fab858"}, 258 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e86d77b090dbddbe78867a0275cb4df08ea195e660f1f7f13435a4649e954e5"}, 259 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4fb39a81950ec280984b3a44f5bd12819953dc5fa3a7e6fa7a80db5ee853952"}, 260 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dee8e57f052ef5353cf608e0b4c871aee320dd1b87d351c28764fc0ca55f9f4"}, 261 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8700f06d0ce6f128de3ccdbc1acaea1ee264d2caa9ca05daaf492fde7c2a7200"}, 262 | {file = "charset_normalizer-3.2.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1920d4ff15ce893210c1f0c0e9d19bfbecb7983c76b33f046c13a8ffbd570252"}, 263 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c1c76a1743432b4b60ab3358c937a3fe1341c828ae6194108a94c69028247f22"}, 264 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f7560358a6811e52e9c4d142d497f1a6e10103d3a6881f18d04dbce3729c0e2c"}, 265 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:c8063cf17b19661471ecbdb3df1c84f24ad2e389e326ccaf89e3fb2484d8dd7e"}, 266 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cd6dbe0238f7743d0efe563ab46294f54f9bc8f4b9bcf57c3c666cc5bc9d1299"}, 267 | {file = "charset_normalizer-3.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1249cbbf3d3b04902ff081ffbb33ce3377fa6e4c7356f759f3cd076cc138d020"}, 268 | {file = "charset_normalizer-3.2.0-cp39-cp39-win32.whl", hash = "sha256:6c409c0deba34f147f77efaa67b8e4bb83d2f11c8806405f76397ae5b8c0d1c9"}, 269 | {file = "charset_normalizer-3.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:7095f6fbfaa55defb6b733cfeb14efaae7a29f0b59d8cf213be4e7ca0b857b80"}, 270 | {file = "charset_normalizer-3.2.0-py3-none-any.whl", hash = "sha256:8e098148dd37b4ce3baca71fb394c81dc5d9c7728c95df695d2dca218edf40e6"}, 271 | ] 272 | 273 | [package.source] 274 | type = "legacy" 275 | url = "https://mirrors.aliyun.com/pypi/simple" 276 | reference = "aliyun" 277 | 278 | [[package]] 279 | name = "click" 280 | version = "8.1.6" 281 | description = "Composable command line interface toolkit" 282 | optional = false 283 | python-versions = ">=3.7" 284 | files = [ 285 | {file = "click-8.1.6-py3-none-any.whl", hash = "sha256:fa244bb30b3b5ee2cae3da8f55c9e5e0c0e86093306301fb418eb9dc40fbded5"}, 286 | {file = "click-8.1.6.tar.gz", hash = "sha256:48ee849951919527a045bfe3bf7baa8a959c423134e1a5b98c05c20ba75a1cbd"}, 287 | ] 288 | 289 | [package.dependencies] 290 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 291 | 292 | [package.source] 293 | type = "legacy" 294 | url = "https://mirrors.aliyun.com/pypi/simple" 295 | reference = "aliyun" 296 | 297 | [[package]] 298 | name = "colorama" 299 | version = "0.4.6" 300 | description = "Cross-platform colored terminal text." 301 | optional = false 302 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 303 | files = [ 304 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 305 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 306 | ] 307 | 308 | [package.source] 309 | type = "legacy" 310 | url = "https://mirrors.aliyun.com/pypi/simple" 311 | reference = "aliyun" 312 | 313 | [[package]] 314 | name = "cookiecutter" 315 | version = "2.2.3" 316 | description = "A command-line utility that creates projects from project templates, e.g. creating a Python package project from a Python package project template." 317 | optional = false 318 | python-versions = ">=3.7" 319 | files = [ 320 | {file = "cookiecutter-2.2.3-py3-none-any.whl", hash = "sha256:17ad6751aef0a39d004c5ecacbd18176de6e83505343073fd7e48b60bdac5254"}, 321 | {file = "cookiecutter-2.2.3.tar.gz", hash = "sha256:d56f18c0c01c09804450b501ac43e8f6104cfa7cdd93610359c68b1ba9fd84d2"}, 322 | ] 323 | 324 | [package.dependencies] 325 | arrow = "*" 326 | binaryornot = ">=0.4.4" 327 | click = ">=7.0,<9.0.0" 328 | Jinja2 = ">=2.7,<4.0.0" 329 | python-slugify = ">=4.0.0" 330 | pyyaml = ">=5.3.1" 331 | requests = ">=2.23.0" 332 | 333 | [package.source] 334 | type = "legacy" 335 | url = "https://mirrors.aliyun.com/pypi/simple" 336 | reference = "aliyun" 337 | 338 | [[package]] 339 | name = "distlib" 340 | version = "0.3.7" 341 | description = "Distribution utilities" 342 | optional = false 343 | python-versions = "*" 344 | files = [ 345 | {file = "distlib-0.3.7-py2.py3-none-any.whl", hash = "sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057"}, 346 | {file = "distlib-0.3.7.tar.gz", hash = "sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8"}, 347 | ] 348 | 349 | [package.source] 350 | type = "legacy" 351 | url = "https://mirrors.aliyun.com/pypi/simple" 352 | reference = "aliyun" 353 | 354 | [[package]] 355 | name = "exceptiongroup" 356 | version = "1.1.2" 357 | description = "Backport of PEP 654 (exception groups)" 358 | optional = false 359 | python-versions = ">=3.7" 360 | files = [ 361 | {file = "exceptiongroup-1.1.2-py3-none-any.whl", hash = "sha256:e346e69d186172ca7cf029c8c1d16235aa0e04035e5750b4b95039e65204328f"}, 362 | {file = "exceptiongroup-1.1.2.tar.gz", hash = "sha256:12c3e887d6485d16943a309616de20ae5582633e0a2eda17f4e10fd61c1e8af5"}, 363 | ] 364 | 365 | [package.extras] 366 | test = ["pytest (>=6)"] 367 | 368 | [package.source] 369 | type = "legacy" 370 | url = "https://mirrors.aliyun.com/pypi/simple" 371 | reference = "aliyun" 372 | 373 | [[package]] 374 | name = "filelock" 375 | version = "3.12.2" 376 | description = "A platform independent file lock." 377 | optional = false 378 | python-versions = ">=3.7" 379 | files = [ 380 | {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, 381 | {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, 382 | ] 383 | 384 | [package.extras] 385 | docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] 386 | testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] 387 | 388 | [package.source] 389 | type = "legacy" 390 | url = "https://mirrors.aliyun.com/pypi/simple" 391 | reference = "aliyun" 392 | 393 | [[package]] 394 | name = "h11" 395 | version = "0.14.0" 396 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" 397 | optional = false 398 | python-versions = ">=3.7" 399 | files = [ 400 | {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, 401 | {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, 402 | ] 403 | 404 | [package.source] 405 | type = "legacy" 406 | url = "https://mirrors.aliyun.com/pypi/simple" 407 | reference = "aliyun" 408 | 409 | [[package]] 410 | name = "httpcore" 411 | version = "0.17.3" 412 | description = "A minimal low-level HTTP client." 413 | optional = false 414 | python-versions = ">=3.7" 415 | files = [ 416 | {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, 417 | {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, 418 | ] 419 | 420 | [package.dependencies] 421 | anyio = ">=3.0,<5.0" 422 | certifi = "*" 423 | h11 = ">=0.13,<0.15" 424 | sniffio = "==1.*" 425 | 426 | [package.extras] 427 | http2 = ["h2 (>=3,<5)"] 428 | socks = ["socksio (==1.*)"] 429 | 430 | [package.source] 431 | type = "legacy" 432 | url = "https://mirrors.aliyun.com/pypi/simple" 433 | reference = "aliyun" 434 | 435 | [[package]] 436 | name = "httpx" 437 | version = "0.24.1" 438 | description = "The next generation HTTP client." 439 | optional = false 440 | python-versions = ">=3.7" 441 | files = [ 442 | {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, 443 | {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, 444 | ] 445 | 446 | [package.dependencies] 447 | certifi = "*" 448 | httpcore = ">=0.15.0,<0.18.0" 449 | idna = "*" 450 | sniffio = "*" 451 | 452 | [package.extras] 453 | brotli = ["brotli", "brotlicffi"] 454 | cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] 455 | http2 = ["h2 (>=3,<5)"] 456 | socks = ["socksio (==1.*)"] 457 | 458 | [package.source] 459 | type = "legacy" 460 | url = "https://mirrors.aliyun.com/pypi/simple" 461 | reference = "aliyun" 462 | 463 | [[package]] 464 | name = "identify" 465 | version = "2.5.26" 466 | description = "File identification library for Python" 467 | optional = false 468 | python-versions = ">=3.8" 469 | files = [ 470 | {file = "identify-2.5.26-py2.py3-none-any.whl", hash = "sha256:c22a8ead0d4ca11f1edd6c9418c3220669b3b7533ada0a0ffa6cc0ef85cf9b54"}, 471 | {file = "identify-2.5.26.tar.gz", hash = "sha256:7243800bce2f58404ed41b7c002e53d4d22bcf3ae1b7900c2d7aefd95394bf7f"}, 472 | ] 473 | 474 | [package.extras] 475 | license = ["ukkonen"] 476 | 477 | [package.source] 478 | type = "legacy" 479 | url = "https://mirrors.aliyun.com/pypi/simple" 480 | reference = "aliyun" 481 | 482 | [[package]] 483 | name = "idna" 484 | version = "3.4" 485 | description = "Internationalized Domain Names in Applications (IDNA)" 486 | optional = false 487 | python-versions = ">=3.5" 488 | files = [ 489 | {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, 490 | {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, 491 | ] 492 | 493 | [package.source] 494 | type = "legacy" 495 | url = "https://mirrors.aliyun.com/pypi/simple" 496 | reference = "aliyun" 497 | 498 | [[package]] 499 | name = "importlib-metadata" 500 | version = "6.8.0" 501 | description = "Read metadata from Python packages" 502 | optional = false 503 | python-versions = ">=3.8" 504 | files = [ 505 | {file = "importlib_metadata-6.8.0-py3-none-any.whl", hash = "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb"}, 506 | {file = "importlib_metadata-6.8.0.tar.gz", hash = "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743"}, 507 | ] 508 | 509 | [package.dependencies] 510 | zipp = ">=0.5" 511 | 512 | [package.extras] 513 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 514 | perf = ["ipython"] 515 | testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] 516 | 517 | [package.source] 518 | type = "legacy" 519 | url = "https://mirrors.aliyun.com/pypi/simple" 520 | reference = "aliyun" 521 | 522 | [[package]] 523 | name = "jinja2" 524 | version = "3.1.2" 525 | description = "A very fast and expressive template engine." 526 | optional = false 527 | python-versions = ">=3.7" 528 | files = [ 529 | {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, 530 | {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, 531 | ] 532 | 533 | [package.dependencies] 534 | MarkupSafe = ">=2.0" 535 | 536 | [package.extras] 537 | i18n = ["Babel (>=2.7)"] 538 | 539 | [package.source] 540 | type = "legacy" 541 | url = "https://mirrors.aliyun.com/pypi/simple" 542 | reference = "aliyun" 543 | 544 | [[package]] 545 | name = "markdown-it-py" 546 | version = "3.0.0" 547 | description = "Python port of markdown-it. Markdown parsing, done right!" 548 | optional = false 549 | python-versions = ">=3.8" 550 | files = [ 551 | {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, 552 | {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, 553 | ] 554 | 555 | [package.dependencies] 556 | mdurl = ">=0.1,<1.0" 557 | 558 | [package.extras] 559 | benchmarking = ["psutil", "pytest", "pytest-benchmark"] 560 | code-style = ["pre-commit (>=3.0,<4.0)"] 561 | compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] 562 | linkify = ["linkify-it-py (>=1,<3)"] 563 | plugins = ["mdit-py-plugins"] 564 | profiling = ["gprof2dot"] 565 | rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] 566 | testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] 567 | 568 | [package.source] 569 | type = "legacy" 570 | url = "https://mirrors.aliyun.com/pypi/simple" 571 | reference = "aliyun" 572 | 573 | [[package]] 574 | name = "markupsafe" 575 | version = "2.1.3" 576 | description = "Safely add untrusted strings to HTML/XML markup." 577 | optional = false 578 | python-versions = ">=3.7" 579 | files = [ 580 | {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, 581 | {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, 582 | {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, 583 | {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, 584 | {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, 585 | {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, 586 | {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, 587 | {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, 588 | {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, 589 | {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, 590 | {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, 591 | {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, 592 | {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, 593 | {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, 594 | {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, 595 | {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, 596 | {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, 597 | {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, 598 | {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, 599 | {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, 600 | {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, 601 | {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, 602 | {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, 603 | {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, 604 | {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, 605 | {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, 606 | {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, 607 | {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, 608 | {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, 609 | {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, 610 | {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, 611 | {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, 612 | {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, 613 | {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, 614 | {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, 615 | {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, 616 | {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, 617 | {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, 618 | {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, 619 | {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, 620 | {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, 621 | {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, 622 | {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, 623 | {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, 624 | {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, 625 | {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, 626 | {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, 627 | {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, 628 | {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, 629 | {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, 630 | ] 631 | 632 | [package.source] 633 | type = "legacy" 634 | url = "https://mirrors.aliyun.com/pypi/simple" 635 | reference = "aliyun" 636 | 637 | [[package]] 638 | name = "mdurl" 639 | version = "0.1.2" 640 | description = "Markdown URL utilities" 641 | optional = false 642 | python-versions = ">=3.7" 643 | files = [ 644 | {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, 645 | {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, 646 | ] 647 | 648 | [package.source] 649 | type = "legacy" 650 | url = "https://mirrors.aliyun.com/pypi/simple" 651 | reference = "aliyun" 652 | 653 | [[package]] 654 | name = "mypy-extensions" 655 | version = "1.0.0" 656 | description = "Type system extensions for programs checked with the mypy type checker." 657 | optional = false 658 | python-versions = ">=3.5" 659 | files = [ 660 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 661 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 662 | ] 663 | 664 | [package.source] 665 | type = "legacy" 666 | url = "https://mirrors.aliyun.com/pypi/simple" 667 | reference = "aliyun" 668 | 669 | [[package]] 670 | name = "nb-cli" 671 | version = "1.2.2" 672 | description = "CLI for nonebot2" 673 | optional = false 674 | python-versions = ">=3.8, <4.0" 675 | files = [ 676 | {file = "nb-cli-1.2.2.tar.gz", hash = "sha256:ecef59e636dd86672beea516932d42c134068572c160ab09d0e541ebe838912f"}, 677 | {file = "nb_cli-1.2.2-py3-none-any.whl", hash = "sha256:b38079daae7ad97a12ed1f2c58d8e3b611b7b01718b368f893effecfeda7ed09"}, 678 | ] 679 | 680 | [package.dependencies] 681 | anyio = ">=3.6,<4.0" 682 | cashews = ">=6.0,<7.0" 683 | click = ">=8.1,<9.0" 684 | cookiecutter = ">=2.2,<3.0" 685 | httpx = ">=0.18,<1.0" 686 | importlib-metadata = {version = ">=4.6", markers = "python_version < \"3.10\""} 687 | jinja2 = ">=3.0,<4.0" 688 | noneprompt = ">=0.1.9,<1.0.0" 689 | pydantic = ">=1.9,<2.0" 690 | pyfiglet = ">=0.8.post1,<1.0.0" 691 | tomlkit = ">=0.10,<1.0" 692 | typing-extensions = ">=4.4,<5.0" 693 | virtualenv = ">=20.17.1,<20.18.0" 694 | watchfiles = ">=0.16,<1.0" 695 | wcwidth = ">=0.2,<1.0" 696 | 697 | [package.source] 698 | type = "legacy" 699 | url = "https://mirrors.aliyun.com/pypi/simple" 700 | reference = "aliyun" 701 | 702 | [[package]] 703 | name = "nodeenv" 704 | version = "1.8.0" 705 | description = "Node.js virtual environment builder" 706 | optional = false 707 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" 708 | files = [ 709 | {file = "nodeenv-1.8.0-py2.py3-none-any.whl", hash = "sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec"}, 710 | {file = "nodeenv-1.8.0.tar.gz", hash = "sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2"}, 711 | ] 712 | 713 | [package.dependencies] 714 | setuptools = "*" 715 | 716 | [package.source] 717 | type = "legacy" 718 | url = "https://mirrors.aliyun.com/pypi/simple" 719 | reference = "aliyun" 720 | 721 | [[package]] 722 | name = "noneprompt" 723 | version = "0.1.9" 724 | description = "Prompt toolkit for console interaction" 725 | optional = false 726 | python-versions = ">=3.8,<4.0" 727 | files = [ 728 | {file = "noneprompt-0.1.9-py3-none-any.whl", hash = "sha256:a54f1e6a19a3da2dedf7f365f80420e9ae49326a0ffe60a8a9c7afdee6b6eeb3"}, 729 | {file = "noneprompt-0.1.9.tar.gz", hash = "sha256:338b8bb89a8d22ef35f1dedb3aa7c1b228cf139973bdc43c5ffc3eef64457db9"}, 730 | ] 731 | 732 | [package.dependencies] 733 | prompt-toolkit = ">=3.0.19,<4.0.0" 734 | 735 | [package.source] 736 | type = "legacy" 737 | url = "https://mirrors.aliyun.com/pypi/simple" 738 | reference = "aliyun" 739 | 740 | [[package]] 741 | name = "packaging" 742 | version = "23.1" 743 | description = "Core utilities for Python packages" 744 | optional = false 745 | python-versions = ">=3.7" 746 | files = [ 747 | {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, 748 | {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, 749 | ] 750 | 751 | [package.source] 752 | type = "legacy" 753 | url = "https://mirrors.aliyun.com/pypi/simple" 754 | reference = "aliyun" 755 | 756 | [[package]] 757 | name = "pathspec" 758 | version = "0.11.1" 759 | description = "Utility library for gitignore style pattern matching of file paths." 760 | optional = false 761 | python-versions = ">=3.7" 762 | files = [ 763 | {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, 764 | {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, 765 | ] 766 | 767 | [package.source] 768 | type = "legacy" 769 | url = "https://mirrors.aliyun.com/pypi/simple" 770 | reference = "aliyun" 771 | 772 | [[package]] 773 | name = "platformdirs" 774 | version = "2.6.2" 775 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 776 | optional = false 777 | python-versions = ">=3.7" 778 | files = [ 779 | {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, 780 | {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, 781 | ] 782 | 783 | [package.extras] 784 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] 785 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] 786 | 787 | [package.source] 788 | type = "legacy" 789 | url = "https://mirrors.aliyun.com/pypi/simple" 790 | reference = "aliyun" 791 | 792 | [[package]] 793 | name = "pre-commit" 794 | version = "3.3.3" 795 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 796 | optional = false 797 | python-versions = ">=3.8" 798 | files = [ 799 | {file = "pre_commit-3.3.3-py2.py3-none-any.whl", hash = "sha256:10badb65d6a38caff29703362271d7dca483d01da88f9d7e05d0b97171c136cb"}, 800 | {file = "pre_commit-3.3.3.tar.gz", hash = "sha256:a2256f489cd913d575c145132ae196fe335da32d91a8294b7afe6622335dd023"}, 801 | ] 802 | 803 | [package.dependencies] 804 | cfgv = ">=2.0.0" 805 | identify = ">=1.0.0" 806 | nodeenv = ">=0.11.1" 807 | pyyaml = ">=5.1" 808 | virtualenv = ">=20.10.0" 809 | 810 | [package.source] 811 | type = "legacy" 812 | url = "https://mirrors.aliyun.com/pypi/simple" 813 | reference = "aliyun" 814 | 815 | [[package]] 816 | name = "prompt-toolkit" 817 | version = "3.0.39" 818 | description = "Library for building powerful interactive command lines in Python" 819 | optional = false 820 | python-versions = ">=3.7.0" 821 | files = [ 822 | {file = "prompt_toolkit-3.0.39-py3-none-any.whl", hash = "sha256:9dffbe1d8acf91e3de75f3b544e4842382fc06c6babe903ac9acb74dc6e08d88"}, 823 | {file = "prompt_toolkit-3.0.39.tar.gz", hash = "sha256:04505ade687dc26dc4284b1ad19a83be2f2afe83e7a828ace0c72f3a1df72aac"}, 824 | ] 825 | 826 | [package.dependencies] 827 | wcwidth = "*" 828 | 829 | [package.source] 830 | type = "legacy" 831 | url = "https://mirrors.aliyun.com/pypi/simple" 832 | reference = "aliyun" 833 | 834 | [[package]] 835 | name = "py-cpuinfo" 836 | version = "9.0.0" 837 | description = "Get CPU info with pure Python" 838 | optional = false 839 | python-versions = "*" 840 | files = [ 841 | {file = "py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690"}, 842 | {file = "py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5"}, 843 | ] 844 | 845 | [package.source] 846 | type = "legacy" 847 | url = "https://mirrors.aliyun.com/pypi/simple" 848 | reference = "aliyun" 849 | 850 | [[package]] 851 | name = "pydantic" 852 | version = "1.10.12" 853 | description = "Data validation and settings management using python type hints" 854 | optional = false 855 | python-versions = ">=3.7" 856 | files = [ 857 | {file = "pydantic-1.10.12-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a1fcb59f2f355ec350073af41d927bf83a63b50e640f4dbaa01053a28b7a7718"}, 858 | {file = "pydantic-1.10.12-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b7ccf02d7eb340b216ec33e53a3a629856afe1c6e0ef91d84a4e6f2fb2ca70fe"}, 859 | {file = "pydantic-1.10.12-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fb2aa3ab3728d950bcc885a2e9eff6c8fc40bc0b7bb434e555c215491bcf48b"}, 860 | {file = "pydantic-1.10.12-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:771735dc43cf8383959dc9b90aa281f0b6092321ca98677c5fb6125a6f56d58d"}, 861 | {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ca48477862372ac3770969b9d75f1bf66131d386dba79506c46d75e6b48c1e09"}, 862 | {file = "pydantic-1.10.12-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a5e7add47a5b5a40c49b3036d464e3c7802f8ae0d1e66035ea16aa5b7a3923ed"}, 863 | {file = "pydantic-1.10.12-cp310-cp310-win_amd64.whl", hash = "sha256:e4129b528c6baa99a429f97ce733fff478ec955513630e61b49804b6cf9b224a"}, 864 | {file = "pydantic-1.10.12-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b0d191db0f92dfcb1dec210ca244fdae5cbe918c6050b342d619c09d31eea0cc"}, 865 | {file = "pydantic-1.10.12-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:795e34e6cc065f8f498c89b894a3c6da294a936ee71e644e4bd44de048af1405"}, 866 | {file = "pydantic-1.10.12-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69328e15cfda2c392da4e713443c7dbffa1505bc9d566e71e55abe14c97ddc62"}, 867 | {file = "pydantic-1.10.12-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2031de0967c279df0d8a1c72b4ffc411ecd06bac607a212892757db7462fc494"}, 868 | {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ba5b2e6fe6ca2b7e013398bc7d7b170e21cce322d266ffcd57cca313e54fb246"}, 869 | {file = "pydantic-1.10.12-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2a7bac939fa326db1ab741c9d7f44c565a1d1e80908b3797f7f81a4f86bc8d33"}, 870 | {file = "pydantic-1.10.12-cp311-cp311-win_amd64.whl", hash = "sha256:87afda5539d5140cb8ba9e8b8c8865cb5b1463924d38490d73d3ccfd80896b3f"}, 871 | {file = "pydantic-1.10.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:549a8e3d81df0a85226963611950b12d2d334f214436a19537b2efed61b7639a"}, 872 | {file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:598da88dfa127b666852bef6d0d796573a8cf5009ffd62104094a4fe39599565"}, 873 | {file = "pydantic-1.10.12-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba5c4a8552bff16c61882db58544116d021d0b31ee7c66958d14cf386a5b5350"}, 874 | {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c79e6a11a07da7374f46970410b41d5e266f7f38f6a17a9c4823db80dadf4303"}, 875 | {file = "pydantic-1.10.12-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab26038b8375581dc832a63c948f261ae0aa21f1d34c1293469f135fa92972a5"}, 876 | {file = "pydantic-1.10.12-cp37-cp37m-win_amd64.whl", hash = "sha256:e0a16d274b588767602b7646fa05af2782576a6cf1022f4ba74cbb4db66f6ca8"}, 877 | {file = "pydantic-1.10.12-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6a9dfa722316f4acf4460afdf5d41d5246a80e249c7ff475c43a3a1e9d75cf62"}, 878 | {file = "pydantic-1.10.12-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a73f489aebd0c2121ed974054cb2759af8a9f747de120acd2c3394cf84176ccb"}, 879 | {file = "pydantic-1.10.12-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bcb8cbfccfcf02acb8f1a261143fab622831d9c0989707e0e659f77a18e0"}, 880 | {file = "pydantic-1.10.12-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fcfb5296d7877af406ba1547dfde9943b1256d8928732267e2653c26938cd9c"}, 881 | {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2f9a6fab5f82ada41d56b0602606a5506aab165ca54e52bc4545028382ef1c5d"}, 882 | {file = "pydantic-1.10.12-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:dea7adcc33d5d105896401a1f37d56b47d443a2b2605ff8a969a0ed5543f7e33"}, 883 | {file = "pydantic-1.10.12-cp38-cp38-win_amd64.whl", hash = "sha256:1eb2085c13bce1612da8537b2d90f549c8cbb05c67e8f22854e201bde5d98a47"}, 884 | {file = "pydantic-1.10.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ef6c96b2baa2100ec91a4b428f80d8f28a3c9e53568219b6c298c1125572ebc6"}, 885 | {file = "pydantic-1.10.12-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c076be61cd0177a8433c0adcb03475baf4ee91edf5a4e550161ad57fc90f523"}, 886 | {file = "pydantic-1.10.12-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d5a58feb9a39f481eda4d5ca220aa8b9d4f21a41274760b9bc66bfd72595b86"}, 887 | {file = "pydantic-1.10.12-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5f805d2d5d0a41633651a73fa4ecdd0b3d7a49de4ec3fadf062fe16501ddbf1"}, 888 | {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1289c180abd4bd4555bb927c42ee42abc3aee02b0fb2d1223fb7c6e5bef87dbe"}, 889 | {file = "pydantic-1.10.12-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5d1197e462e0364906cbc19681605cb7c036f2475c899b6f296104ad42b9f5fb"}, 890 | {file = "pydantic-1.10.12-cp39-cp39-win_amd64.whl", hash = "sha256:fdbdd1d630195689f325c9ef1a12900524dceb503b00a987663ff4f58669b93d"}, 891 | {file = "pydantic-1.10.12-py3-none-any.whl", hash = "sha256:b749a43aa51e32839c9d71dc67eb1e4221bb04af1033a32e3923d46f9effa942"}, 892 | {file = "pydantic-1.10.12.tar.gz", hash = "sha256:0fe8a415cea8f340e7a9af9c54fc71a649b43e8ca3cc732986116b3cb135d303"}, 893 | ] 894 | 895 | [package.dependencies] 896 | typing-extensions = ">=4.2.0" 897 | 898 | [package.extras] 899 | dotenv = ["python-dotenv (>=0.10.4)"] 900 | email = ["email-validator (>=1.0.3)"] 901 | 902 | [package.source] 903 | type = "legacy" 904 | url = "https://mirrors.aliyun.com/pypi/simple" 905 | reference = "aliyun" 906 | 907 | [[package]] 908 | name = "pyfiglet" 909 | version = "0.8.post1" 910 | description = "Pure-python FIGlet implementation" 911 | optional = false 912 | python-versions = "*" 913 | files = [ 914 | {file = "pyfiglet-0.8.post1-py2.py3-none-any.whl", hash = "sha256:d555bcea17fbeaf70eaefa48bb119352487e629c9b56f30f383e2c62dd67a01c"}, 915 | {file = "pyfiglet-0.8.post1.tar.gz", hash = "sha256:c6c2321755d09267b438ec7b936825a4910fec696292139e664ca8670e103639"}, 916 | ] 917 | 918 | [package.source] 919 | type = "legacy" 920 | url = "https://mirrors.aliyun.com/pypi/simple" 921 | reference = "aliyun" 922 | 923 | [[package]] 924 | name = "pygments" 925 | version = "2.15.1" 926 | description = "Pygments is a syntax highlighting package written in Python." 927 | optional = false 928 | python-versions = ">=3.7" 929 | files = [ 930 | {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, 931 | {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, 932 | ] 933 | 934 | [package.extras] 935 | plugins = ["importlib-metadata"] 936 | 937 | [package.source] 938 | type = "legacy" 939 | url = "https://mirrors.aliyun.com/pypi/simple" 940 | reference = "aliyun" 941 | 942 | [[package]] 943 | name = "python-dateutil" 944 | version = "2.8.2" 945 | description = "Extensions to the standard Python datetime module" 946 | optional = false 947 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 948 | files = [ 949 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, 950 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, 951 | ] 952 | 953 | [package.dependencies] 954 | six = ">=1.5" 955 | 956 | [package.source] 957 | type = "legacy" 958 | url = "https://mirrors.aliyun.com/pypi/simple" 959 | reference = "aliyun" 960 | 961 | [[package]] 962 | name = "python-slugify" 963 | version = "8.0.1" 964 | description = "A Python slugify application that also handles Unicode" 965 | optional = false 966 | python-versions = ">=3.7" 967 | files = [ 968 | {file = "python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"}, 969 | {file = "python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"}, 970 | ] 971 | 972 | [package.dependencies] 973 | text-unidecode = ">=1.3" 974 | 975 | [package.extras] 976 | unidecode = ["Unidecode (>=1.1.1)"] 977 | 978 | [package.source] 979 | type = "legacy" 980 | url = "https://mirrors.aliyun.com/pypi/simple" 981 | reference = "aliyun" 982 | 983 | [[package]] 984 | name = "pyyaml" 985 | version = "6.0.1" 986 | description = "YAML parser and emitter for Python" 987 | optional = false 988 | python-versions = ">=3.6" 989 | files = [ 990 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, 991 | {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, 992 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, 993 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, 994 | {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, 995 | {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, 996 | {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, 997 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, 998 | {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, 999 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, 1000 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, 1001 | {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, 1002 | {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, 1003 | {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, 1004 | {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, 1005 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, 1006 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, 1007 | {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, 1008 | {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, 1009 | {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, 1010 | {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, 1011 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, 1012 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, 1013 | {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, 1014 | {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, 1015 | {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, 1016 | {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, 1017 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, 1018 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, 1019 | {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, 1020 | {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, 1021 | {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, 1022 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, 1023 | {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, 1024 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, 1025 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, 1026 | {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, 1027 | {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, 1028 | {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, 1029 | {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, 1030 | ] 1031 | 1032 | [package.source] 1033 | type = "legacy" 1034 | url = "https://mirrors.aliyun.com/pypi/simple" 1035 | reference = "aliyun" 1036 | 1037 | [[package]] 1038 | name = "requests" 1039 | version = "2.31.0" 1040 | description = "Python HTTP for Humans." 1041 | optional = false 1042 | python-versions = ">=3.7" 1043 | files = [ 1044 | {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, 1045 | {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, 1046 | ] 1047 | 1048 | [package.dependencies] 1049 | certifi = ">=2017.4.17" 1050 | charset-normalizer = ">=2,<4" 1051 | idna = ">=2.5,<4" 1052 | urllib3 = ">=1.21.1,<3" 1053 | 1054 | [package.extras] 1055 | socks = ["PySocks (>=1.5.6,!=1.5.7)"] 1056 | use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] 1057 | 1058 | [package.source] 1059 | type = "legacy" 1060 | url = "https://mirrors.aliyun.com/pypi/simple" 1061 | reference = "aliyun" 1062 | 1063 | [[package]] 1064 | name = "rich" 1065 | version = "13.4.2" 1066 | description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" 1067 | optional = false 1068 | python-versions = ">=3.7.0" 1069 | files = [ 1070 | {file = "rich-13.4.2-py3-none-any.whl", hash = "sha256:8f87bc7ee54675732fa66a05ebfe489e27264caeeff3728c945d25971b6485ec"}, 1071 | {file = "rich-13.4.2.tar.gz", hash = "sha256:d653d6bccede5844304c605d5aac802c7cf9621efd700b46c7ec2b51ea914898"}, 1072 | ] 1073 | 1074 | [package.dependencies] 1075 | markdown-it-py = ">=2.2.0" 1076 | pygments = ">=2.13.0,<3.0.0" 1077 | typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} 1078 | 1079 | [package.extras] 1080 | jupyter = ["ipywidgets (>=7.5.1,<9)"] 1081 | 1082 | [package.source] 1083 | type = "legacy" 1084 | url = "https://mirrors.aliyun.com/pypi/simple" 1085 | reference = "aliyun" 1086 | 1087 | [[package]] 1088 | name = "ruff" 1089 | version = "0.0.277" 1090 | description = "An extremely fast Python linter, written in Rust." 1091 | optional = false 1092 | python-versions = ">=3.7" 1093 | files = [ 1094 | {file = "ruff-0.0.277-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:3250b24333ef419b7a232080d9724ccc4d2da1dbbe4ce85c4caa2290d83200f8"}, 1095 | {file = "ruff-0.0.277-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:3e60605e07482183ba1c1b7237eca827bd6cbd3535fe8a4ede28cbe2a323cb97"}, 1096 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7baa97c3d7186e5ed4d5d4f6834d759a27e56cf7d5874b98c507335f0ad5aadb"}, 1097 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:74e4b206cb24f2e98a615f87dbe0bde18105217cbcc8eb785bb05a644855ba50"}, 1098 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:479864a3ccd8a6a20a37a6e7577bdc2406868ee80b1e65605478ad3b8eb2ba0b"}, 1099 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:468bfb0a7567443cec3d03cf408d6f562b52f30c3c29df19927f1e0e13a40cd7"}, 1100 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f32ec416c24542ca2f9cc8c8b65b84560530d338aaf247a4a78e74b99cd476b4"}, 1101 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:14a7b2f00f149c5a295f188a643ac25226ff8a4d08f7a62b1d4b0a1dc9f9b85c"}, 1102 | {file = "ruff-0.0.277-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9879f59f763cc5628aa01c31ad256a0f4dc61a29355c7315b83c2a5aac932b5"}, 1103 | {file = "ruff-0.0.277-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:f612e0a14b3d145d90eb6ead990064e22f6f27281d847237560b4e10bf2251f3"}, 1104 | {file = "ruff-0.0.277-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:323b674c98078be9aaded5b8b51c0d9c424486566fb6ec18439b496ce79e5998"}, 1105 | {file = "ruff-0.0.277-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3a43fbe026ca1a2a8c45aa0d600a0116bec4dfa6f8bf0c3b871ecda51ef2b5dd"}, 1106 | {file = "ruff-0.0.277-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:734165ea8feb81b0d53e3bf523adc2413fdb76f1264cde99555161dd5a725522"}, 1107 | {file = "ruff-0.0.277-py3-none-win32.whl", hash = "sha256:88d0f2afb2e0c26ac1120e7061ddda2a566196ec4007bd66d558f13b374b9efc"}, 1108 | {file = "ruff-0.0.277-py3-none-win_amd64.whl", hash = "sha256:6fe81732f788894a00f6ade1fe69e996cc9e485b7c35b0f53fb00284397284b2"}, 1109 | {file = "ruff-0.0.277-py3-none-win_arm64.whl", hash = "sha256:2d4444c60f2e705c14cd802b55cd2b561d25bf4311702c463a002392d3116b22"}, 1110 | {file = "ruff-0.0.277.tar.gz", hash = "sha256:2dab13cdedbf3af6d4427c07f47143746b6b95d9e4a254ac369a0edb9280a0d2"}, 1111 | ] 1112 | 1113 | [package.source] 1114 | type = "legacy" 1115 | url = "https://mirrors.aliyun.com/pypi/simple" 1116 | reference = "aliyun" 1117 | 1118 | [[package]] 1119 | name = "setuptools" 1120 | version = "68.0.0" 1121 | description = "Easily download, build, install, upgrade, and uninstall Python packages" 1122 | optional = false 1123 | python-versions = ">=3.7" 1124 | files = [ 1125 | {file = "setuptools-68.0.0-py3-none-any.whl", hash = "sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f"}, 1126 | {file = "setuptools-68.0.0.tar.gz", hash = "sha256:baf1fdb41c6da4cd2eae722e135500da913332ab3f2f5c7d33af9b492acb5235"}, 1127 | ] 1128 | 1129 | [package.extras] 1130 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] 1131 | testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 1132 | testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] 1133 | 1134 | [package.source] 1135 | type = "legacy" 1136 | url = "https://mirrors.aliyun.com/pypi/simple" 1137 | reference = "aliyun" 1138 | 1139 | [[package]] 1140 | name = "six" 1141 | version = "1.16.0" 1142 | description = "Python 2 and 3 compatibility utilities" 1143 | optional = false 1144 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 1145 | files = [ 1146 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 1147 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 1148 | ] 1149 | 1150 | [package.source] 1151 | type = "legacy" 1152 | url = "https://mirrors.aliyun.com/pypi/simple" 1153 | reference = "aliyun" 1154 | 1155 | [[package]] 1156 | name = "sniffio" 1157 | version = "1.3.0" 1158 | description = "Sniff out which async library your code is running under" 1159 | optional = false 1160 | python-versions = ">=3.7" 1161 | files = [ 1162 | {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, 1163 | {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, 1164 | ] 1165 | 1166 | [package.source] 1167 | type = "legacy" 1168 | url = "https://mirrors.aliyun.com/pypi/simple" 1169 | reference = "aliyun" 1170 | 1171 | [[package]] 1172 | name = "text-unidecode" 1173 | version = "1.3" 1174 | description = "The most basic Text::Unidecode port" 1175 | optional = false 1176 | python-versions = "*" 1177 | files = [ 1178 | {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, 1179 | {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, 1180 | ] 1181 | 1182 | [package.source] 1183 | type = "legacy" 1184 | url = "https://mirrors.aliyun.com/pypi/simple" 1185 | reference = "aliyun" 1186 | 1187 | [[package]] 1188 | name = "tomli" 1189 | version = "2.0.1" 1190 | description = "A lil' TOML parser" 1191 | optional = false 1192 | python-versions = ">=3.7" 1193 | files = [ 1194 | {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, 1195 | {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, 1196 | ] 1197 | 1198 | [package.source] 1199 | type = "legacy" 1200 | url = "https://mirrors.aliyun.com/pypi/simple" 1201 | reference = "aliyun" 1202 | 1203 | [[package]] 1204 | name = "tomlkit" 1205 | version = "0.11.8" 1206 | description = "Style preserving TOML library" 1207 | optional = false 1208 | python-versions = ">=3.7" 1209 | files = [ 1210 | {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, 1211 | {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, 1212 | ] 1213 | 1214 | [package.source] 1215 | type = "legacy" 1216 | url = "https://mirrors.aliyun.com/pypi/simple" 1217 | reference = "aliyun" 1218 | 1219 | [[package]] 1220 | name = "typing-extensions" 1221 | version = "4.7.1" 1222 | description = "Backported and Experimental Type Hints for Python 3.7+" 1223 | optional = false 1224 | python-versions = ">=3.7" 1225 | files = [ 1226 | {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, 1227 | {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, 1228 | ] 1229 | 1230 | [package.source] 1231 | type = "legacy" 1232 | url = "https://mirrors.aliyun.com/pypi/simple" 1233 | reference = "aliyun" 1234 | 1235 | [[package]] 1236 | name = "urllib3" 1237 | version = "2.0.4" 1238 | description = "HTTP library with thread-safe connection pooling, file post, and more." 1239 | optional = false 1240 | python-versions = ">=3.7" 1241 | files = [ 1242 | {file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"}, 1243 | {file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"}, 1244 | ] 1245 | 1246 | [package.extras] 1247 | brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] 1248 | secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"] 1249 | socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] 1250 | zstd = ["zstandard (>=0.18.0)"] 1251 | 1252 | [package.source] 1253 | type = "legacy" 1254 | url = "https://mirrors.aliyun.com/pypi/simple" 1255 | reference = "aliyun" 1256 | 1257 | [[package]] 1258 | name = "virtualenv" 1259 | version = "20.17.1" 1260 | description = "Virtual Python Environment builder" 1261 | optional = false 1262 | python-versions = ">=3.6" 1263 | files = [ 1264 | {file = "virtualenv-20.17.1-py3-none-any.whl", hash = "sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4"}, 1265 | {file = "virtualenv-20.17.1.tar.gz", hash = "sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058"}, 1266 | ] 1267 | 1268 | [package.dependencies] 1269 | distlib = ">=0.3.6,<1" 1270 | filelock = ">=3.4.1,<4" 1271 | platformdirs = ">=2.4,<3" 1272 | 1273 | [package.extras] 1274 | docs = ["proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-argparse (>=0.3.2)", "sphinx-rtd-theme (>=1)", "towncrier (>=22.8)"] 1275 | testing = ["coverage (>=6.2)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=21.3)", "pytest (>=7.0.1)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.6.1)", "pytest-randomly (>=3.10.3)", "pytest-timeout (>=2.1)"] 1276 | 1277 | [package.source] 1278 | type = "legacy" 1279 | url = "https://mirrors.aliyun.com/pypi/simple" 1280 | reference = "aliyun" 1281 | 1282 | [[package]] 1283 | name = "watchfiles" 1284 | version = "0.19.0" 1285 | description = "Simple, modern and high performance file watching and code reload in python." 1286 | optional = false 1287 | python-versions = ">=3.7" 1288 | files = [ 1289 | {file = "watchfiles-0.19.0-cp37-abi3-macosx_10_7_x86_64.whl", hash = "sha256:91633e64712df3051ca454ca7d1b976baf842d7a3640b87622b323c55f3345e7"}, 1290 | {file = "watchfiles-0.19.0-cp37-abi3-macosx_11_0_arm64.whl", hash = "sha256:b6577b8c6c8701ba8642ea9335a129836347894b666dd1ec2226830e263909d3"}, 1291 | {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:18b28f6ad871b82df9542ff958d0c86bb0d8310bb09eb8e87d97318a3b5273af"}, 1292 | {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fac19dc9cbc34052394dbe81e149411a62e71999c0a19e1e09ce537867f95ae0"}, 1293 | {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:09ea3397aecbc81c19ed7f025e051a7387feefdb789cf768ff994c1228182fda"}, 1294 | {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c0376deac92377817e4fb8f347bf559b7d44ff556d9bc6f6208dd3f79f104aaf"}, 1295 | {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c75eff897786ee262c9f17a48886f4e98e6cfd335e011c591c305e5d083c056"}, 1296 | {file = "watchfiles-0.19.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb5d45c4143c1dd60f98a16187fd123eda7248f84ef22244818c18d531a249d1"}, 1297 | {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:79c533ff593db861ae23436541f481ec896ee3da4e5db8962429b441bbaae16e"}, 1298 | {file = "watchfiles-0.19.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:3d7d267d27aceeeaa3de0dd161a0d64f0a282264d592e335fff7958cc0cbae7c"}, 1299 | {file = "watchfiles-0.19.0-cp37-abi3-win32.whl", hash = "sha256:176a9a7641ec2c97b24455135d58012a5be5c6217fc4d5fef0b2b9f75dbf5154"}, 1300 | {file = "watchfiles-0.19.0-cp37-abi3-win_amd64.whl", hash = "sha256:945be0baa3e2440151eb3718fd8846751e8b51d8de7b884c90b17d271d34cae8"}, 1301 | {file = "watchfiles-0.19.0-cp37-abi3-win_arm64.whl", hash = "sha256:0089c6dc24d436b373c3c57657bf4f9a453b13767150d17284fc6162b2791911"}, 1302 | {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cae3dde0b4b2078f31527acff6f486e23abed307ba4d3932466ba7cdd5ecec79"}, 1303 | {file = "watchfiles-0.19.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:7f3920b1285a7d3ce898e303d84791b7bf40d57b7695ad549dc04e6a44c9f120"}, 1304 | {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9afd0d69429172c796164fd7fe8e821ade9be983f51c659a38da3faaaaac44dc"}, 1305 | {file = "watchfiles-0.19.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68dce92b29575dda0f8d30c11742a8e2b9b8ec768ae414b54f7453f27bdf9545"}, 1306 | {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5569fc7f967429d4bc87e355cdfdcee6aabe4b620801e2cf5805ea245c06097c"}, 1307 | {file = "watchfiles-0.19.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:5471582658ea56fca122c0f0d0116a36807c63fefd6fdc92c71ca9a4491b6b48"}, 1308 | {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b538014a87f94d92f98f34d3e6d2635478e6be6423a9ea53e4dd96210065e193"}, 1309 | {file = "watchfiles-0.19.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20b44221764955b1e703f012c74015306fb7e79a00c15370785f309b1ed9aa8d"}, 1310 | {file = "watchfiles-0.19.0.tar.gz", hash = "sha256:d9b073073e048081e502b6c6b0b88714c026a1a4c890569238d04aca5f9ca74b"}, 1311 | ] 1312 | 1313 | [package.dependencies] 1314 | anyio = ">=3.0.0" 1315 | 1316 | [package.source] 1317 | type = "legacy" 1318 | url = "https://mirrors.aliyun.com/pypi/simple" 1319 | reference = "aliyun" 1320 | 1321 | [[package]] 1322 | name = "wcwidth" 1323 | version = "0.2.6" 1324 | description = "Measures the displayed width of unicode strings in a terminal" 1325 | optional = false 1326 | python-versions = "*" 1327 | files = [ 1328 | {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, 1329 | {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, 1330 | ] 1331 | 1332 | [package.source] 1333 | type = "legacy" 1334 | url = "https://mirrors.aliyun.com/pypi/simple" 1335 | reference = "aliyun" 1336 | 1337 | [[package]] 1338 | name = "zipp" 1339 | version = "3.16.2" 1340 | description = "Backport of pathlib-compatible object wrapper for zip files" 1341 | optional = false 1342 | python-versions = ">=3.8" 1343 | files = [ 1344 | {file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"}, 1345 | {file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"}, 1346 | ] 1347 | 1348 | [package.extras] 1349 | docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] 1350 | testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] 1351 | 1352 | [package.source] 1353 | type = "legacy" 1354 | url = "https://mirrors.aliyun.com/pypi/simple" 1355 | reference = "aliyun" 1356 | 1357 | [metadata] 1358 | lock-version = "2.0" 1359 | python-versions = "^3.8" 1360 | content-hash = "689c82fb2835de98de45bb9e69053661f28ae0ecfc930faaaae6469bd2fb8a64" 1361 | --------------------------------------------------------------------------------