mirror of
https://gitflic.ru/project/alt-gnome/karkas.git
synced 2024-12-24 00:33:06 +03:00
Merged with experimental/redesign-db-block
This commit is contained in:
commit
aab5fb4e39
@ -33,3 +33,41 @@ repos:
|
|||||||
rev: 1.7.9 # sync:bandit:poetry.lock
|
rev: 1.7.9 # sync:bandit:poetry.lock
|
||||||
hooks:
|
hooks:
|
||||||
- id: bandit
|
- id: bandit
|
||||||
|
- repo: https://github.com/python-poetry/poetry
|
||||||
|
rev: 1.8.3
|
||||||
|
hooks:
|
||||||
|
- name: Poetry Lock (root)
|
||||||
|
id: poetry-lock
|
||||||
|
args: ["--no-update"]
|
||||||
|
- name: Poetry Check (root)
|
||||||
|
id: poetry-check
|
||||||
|
- name: Poetry Lock (gnomik)
|
||||||
|
id: poetry-lock
|
||||||
|
args: ["-C", "./src/gnomik", "--no-update"]
|
||||||
|
- name: Poetry Check (gnomik)
|
||||||
|
id: poetry-check
|
||||||
|
args: ["-C", "./src/gnomik"]
|
||||||
|
- name: Poetry Lock (altlinux)
|
||||||
|
id: poetry-lock
|
||||||
|
args: ["-C", "./src/altlinux", "--no-update"]
|
||||||
|
- name: Poetry Check (altlinux)
|
||||||
|
id: poetry-check
|
||||||
|
args: ["-C", "./src/altlinux"]
|
||||||
|
- name: Poetry Lock (karkas_core)
|
||||||
|
id: poetry-lock
|
||||||
|
args: ["-C", "./src/karkas_core", "--no-update"]
|
||||||
|
- name: Poetry Check (karkas_core)
|
||||||
|
id: poetry-check
|
||||||
|
args: ["-C", "./src/karkas_core"]
|
||||||
|
- name: Poetry Lock (karkas_blocks)
|
||||||
|
id: poetry-lock
|
||||||
|
args: ["-C", "./src/karkas_blocks", "--no-update"]
|
||||||
|
- name: Poetry Check (karkas_blocks)
|
||||||
|
id: poetry-check
|
||||||
|
args: ["-C", "./src/karkas_blocks"]
|
||||||
|
- name: Poetry Lock (karkas_piccolo)
|
||||||
|
id: poetry-lock
|
||||||
|
args: ["-C", "./src/karkas_piccolo", "--no-update"]
|
||||||
|
- name: Poetry Check (karkas_piccolo)
|
||||||
|
id: poetry-check
|
||||||
|
args: ["-C", "./src/karkas_piccolo"]
|
||||||
|
@ -12,6 +12,10 @@
|
|||||||
"name": "Karkas Core",
|
"name": "Karkas Core",
|
||||||
"path": "src/karkas_core"
|
"path": "src/karkas_core"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Karkas Piccolo",
|
||||||
|
"path": "src/karkas_piccolo"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Gnomik",
|
"name": "Gnomik",
|
||||||
"path": "src/gnomik"
|
"path": "src/gnomik"
|
||||||
|
28
poetry.lock
generated
28
poetry.lock
generated
@ -61,6 +61,8 @@ mypy-extensions = ">=0.4.3"
|
|||||||
packaging = ">=22.0"
|
packaging = ">=22.0"
|
||||||
pathspec = ">=0.9.0"
|
pathspec = ">=0.9.0"
|
||||||
platformdirs = ">=2"
|
platformdirs = ">=2"
|
||||||
|
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||||
|
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
colorama = ["colorama (>=0.4.3)"]
|
colorama = ["colorama (>=0.4.3)"]
|
||||||
@ -449,6 +451,28 @@ files = [
|
|||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
pbr = ">=2.0.0,<2.1.0 || >2.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomli"
|
||||||
|
version = "2.0.1"
|
||||||
|
description = "A lil' TOML parser"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||||
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typing-extensions"
|
||||||
|
version = "4.12.2"
|
||||||
|
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
|
||||||
|
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "virtualenv"
|
name = "virtualenv"
|
||||||
version = "20.26.3"
|
version = "20.26.3"
|
||||||
@ -471,5 +495,5 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "~3.12"
|
python-versions = ">=3.10,<3.13"
|
||||||
content-hash = "7db42302f410e90c105f188f32680864d9268137049af500f4221e69b4f9cc7f"
|
content-hash = "71a956a903d10f5fffea9e7ff4528723cbbb873f38016373e7b817bdc72f36f9"
|
||||||
|
@ -25,7 +25,7 @@ init = 'scripts.init:main'
|
|||||||
module = 'scripts.module:main'
|
module = 'scripts.module:main'
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.10,<=3.12"
|
python = ">=3.10,<3.13"
|
||||||
|
|
||||||
[tool.poetry.group.dev.dependencies]
|
[tool.poetry.group.dev.dependencies]
|
||||||
flake8 = "^7.1.0"
|
flake8 = "^7.1.0"
|
||||||
|
154
src/altlinux/poetry.lock
generated
154
src/altlinux/poetry.lock
generated
@ -128,6 +128,7 @@ files = [
|
|||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
aiosignal = ">=1.1.2"
|
aiosignal = ">=1.1.2"
|
||||||
|
async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
|
||||||
attrs = ">=17.3.0"
|
attrs = ">=17.3.0"
|
||||||
frozenlist = ">=1.1.1"
|
frozenlist = ">=1.1.1"
|
||||||
multidict = ">=4.5,<7.0"
|
multidict = ">=4.5,<7.0"
|
||||||
@ -173,14 +174,27 @@ files = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
|
||||||
idna = ">=2.8"
|
idna = ">=2.8"
|
||||||
sniffio = ">=1.1"
|
sniffio = ">=1.1"
|
||||||
|
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
||||||
trio = ["trio (>=0.23)"]
|
trio = ["trio (>=0.23)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-timeout"
|
||||||
|
version = "4.0.3"
|
||||||
|
description = "Timeout context manager for asyncio programs"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
|
||||||
|
{file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
version = "23.2.0"
|
version = "23.2.0"
|
||||||
@ -539,6 +553,20 @@ files = [
|
|||||||
dnspython = ">=2.0.0"
|
dnspython = ">=2.0.0"
|
||||||
idna = ">=2.0.0"
|
idna = ">=2.0.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "exceptiongroup"
|
||||||
|
version = "1.2.2"
|
||||||
|
description = "Backport of PEP 654 (exception groups)"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
|
||||||
|
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
test = ["pytest (>=6)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastapi"
|
name = "fastapi"
|
||||||
version = "0.111.1"
|
version = "0.111.1"
|
||||||
@ -846,9 +874,13 @@ files = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
exceptiongroup = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||||
h11 = "*"
|
h11 = "*"
|
||||||
h2 = ">=3.1.0"
|
h2 = ">=3.1.0"
|
||||||
priority = "*"
|
priority = "*"
|
||||||
|
taskgroup = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
|
tomli = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
|
typing_extensions = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
wsproto = ">=0.14.0"
|
wsproto = ">=0.14.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -940,6 +972,52 @@ files = [
|
|||||||
editorconfig = ">=0.12.2"
|
editorconfig = ">=0.12.2"
|
||||||
six = ">=1.13.0"
|
six = ">=1.13.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "karkas-blocks"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10,<3.13"
|
||||||
|
files = []
|
||||||
|
develop = true
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
dash = "^2.17.1"
|
||||||
|
dash-bootstrap-components = "^1.6.0"
|
||||||
|
dash-extensions = "^1.0.18"
|
||||||
|
karkas-core = {path = "../karkas_core", develop = true}
|
||||||
|
peewee = "^3.17.6"
|
||||||
|
pyyaml = "^6.0.1"
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "../karkas_blocks"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "karkas-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10,<3.13"
|
||||||
|
files = []
|
||||||
|
develop = true
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
aiogram = "^3.10.0"
|
||||||
|
dataclasses-json = "^0.6.7"
|
||||||
|
fastapi = {version = "^0.111.1", optional = true}
|
||||||
|
hypercorn = {version = "^0.17.3", optional = true}
|
||||||
|
restrictedpython = "^7.1"
|
||||||
|
semver = "^3.0.2"
|
||||||
|
setuptools = "^71.0.1"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
webhook = ["fastapi (>=0.111.1,<0.112.0)", "hypercorn (>=0.17.3,<0.18.0)"]
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "../karkas_core"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "magic-filter"
|
name = "magic-filter"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
@ -1209,52 +1287,6 @@ files = [
|
|||||||
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "karkas-core"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = ""
|
|
||||||
optional = false
|
|
||||||
python-versions = "~3.12"
|
|
||||||
files = []
|
|
||||||
develop = true
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
aiogram = "^3.10.0"
|
|
||||||
dataclasses-json = "^0.6.7"
|
|
||||||
fastapi = {version = "^0.111.1", optional = true}
|
|
||||||
hypercorn = {version = "^0.17.3", optional = true}
|
|
||||||
restrictedpython = "^7.1"
|
|
||||||
semver = "^3.0.2"
|
|
||||||
setuptools = "^71.0.1"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
webhook = ["fastapi (>=0.111.1,<0.112.0)", "hypercorn (>=0.17.3,<0.18.0)"]
|
|
||||||
|
|
||||||
[package.source]
|
|
||||||
type = "directory"
|
|
||||||
url = "../karkas_core"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "karkas-blocks"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = ""
|
|
||||||
optional = false
|
|
||||||
python-versions = "~3.12"
|
|
||||||
files = []
|
|
||||||
develop = true
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
dash = "^2.17.1"
|
|
||||||
dash-bootstrap-components = "^1.6.0"
|
|
||||||
dash-extensions = "^1.0.18"
|
|
||||||
karkas-core = {path = "../karkas_core", develop = true}
|
|
||||||
peewee = "^3.17.6"
|
|
||||||
pyyaml = "^6.0.1"
|
|
||||||
|
|
||||||
[package.source]
|
|
||||||
type = "directory"
|
|
||||||
url = "../karkas_blocks"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "24.1"
|
version = "24.1"
|
||||||
@ -1695,6 +1727,20 @@ anyio = ">=3.4.0,<5"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"]
|
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "taskgroup"
|
||||||
|
version = "0.0.0a4"
|
||||||
|
description = "backport of asyncio.TaskGroup, asyncio.Runner and asyncio.timeout"
|
||||||
|
optional = false
|
||||||
|
python-versions = "*"
|
||||||
|
files = [
|
||||||
|
{file = "taskgroup-0.0.0a4-py2.py3-none-any.whl", hash = "sha256:5c1bd0e4c06114e7a4128583ab75c987597d5378a33948a3b74c662b90f61277"},
|
||||||
|
{file = "taskgroup-0.0.0a4.tar.gz", hash = "sha256:eb08902d221e27661950f2a0320ddf3f939f579279996f81fe30779bca3a159c"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
exceptiongroup = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tenacity"
|
name = "tenacity"
|
||||||
version = "8.5.0"
|
version = "8.5.0"
|
||||||
@ -1710,6 +1756,17 @@ files = [
|
|||||||
doc = ["reno", "sphinx"]
|
doc = ["reno", "sphinx"]
|
||||||
test = ["pytest", "tornado (>=4.5)", "typeguard"]
|
test = ["pytest", "tornado (>=4.5)", "typeguard"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomli"
|
||||||
|
version = "2.0.1"
|
||||||
|
description = "A lil' TOML parser"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||||
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typer"
|
name = "typer"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -1788,6 +1845,7 @@ h11 = ">=0.8"
|
|||||||
httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
|
httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
|
||||||
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
||||||
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
||||||
|
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
||||||
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
||||||
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
||||||
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
|
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
|
||||||
@ -2158,5 +2216,5 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools",
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "~3.12"
|
python-versions = ">=3.10,<3.13"
|
||||||
content-hash = "63f870b298f75049e8fb6fe1a5fa9482e4bfb2d624c8bc6bf3dfc6bafa1c05c3"
|
content-hash = "d9a8013e760cfe29900565540b9638ba421dc0f63ae288e785f42d62de17e88c"
|
||||||
|
@ -8,7 +8,7 @@ authors = [
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.10,<=3.12"
|
python = ">=3.10,<3.13"
|
||||||
karkas-core = { extras=["webhook"], path = "../karkas_core", develop = true }
|
karkas-core = { extras=["webhook"], path = "../karkas_core", develop = true }
|
||||||
karkas-blocks = { path = "../karkas_blocks", develop = true }
|
karkas-blocks = { path = "../karkas_blocks", develop = true }
|
||||||
|
|
||||||
|
@ -9,18 +9,22 @@ async def main():
|
|||||||
await ocab.init_app(
|
await ocab.init_app(
|
||||||
[
|
[
|
||||||
block_loader("standard", "config", safe=False),
|
block_loader("standard", "config", safe=False),
|
||||||
|
block_loader("standard", "filters", safe=False),
|
||||||
block_loader("standard", "database", safe=False),
|
block_loader("standard", "database", safe=False),
|
||||||
block_loader("standard", "fsm_database_storage", safe=False),
|
block_loader("standard", "statistics", safe=False),
|
||||||
block_loader("standard", "roles", safe=False),
|
block_loader("standard", "chats", safe=False),
|
||||||
block_loader("external", "yandexgpt", safe=False),
|
block_loader("standard", "users", safe=False),
|
||||||
#
|
|
||||||
block_loader("standard", "command_helper"),
|
block_loader("standard", "command_helper"),
|
||||||
block_loader("standard", "info"),
|
block_loader("standard", "roles", safe=False),
|
||||||
block_loader("standard", "filters"),
|
block_loader("standard", "fsm_database_storage", safe=False),
|
||||||
block_loader("external", "create_report_apps"),
|
block_loader("external", "create_report_apps"),
|
||||||
block_loader("standard", "admin"),
|
block_loader("standard", "info"),
|
||||||
block_loader("standard", "message_processing"),
|
block_loader("standard", "help"),
|
||||||
block_loader("standard", "miniapp", safe=False),
|
# block_loader("external", "yandexgpt", safe=False),
|
||||||
|
#
|
||||||
|
# block_loader("standard", "admin"),
|
||||||
|
# block_loader("standard", "message_processing"),
|
||||||
|
# block_loader("standard", "miniapp", safe=False),
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
await ocab.start()
|
await ocab.start()
|
||||||
|
931
src/gnomik/poetry.lock
generated
931
src/gnomik/poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -6,9 +6,10 @@ authors = ["Максим Слипенко <maxim@slipenko.com>"]
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.10,<=3.12"
|
python = ">=3.10,<3.13"
|
||||||
karkas-core = { extras=["webhook"], path = "../karkas_core", develop = true }
|
karkas-core = { extras=["webhook"], path = "../karkas_core", develop = true }
|
||||||
karkas-blocks = { path = "../karkas_blocks", develop = true }
|
karkas-blocks = { path = "../karkas_blocks", develop = true }
|
||||||
|
karkas-piccolo = { path = "../karkas_piccolo", develop = true }
|
||||||
|
|
||||||
[build-system]
|
[build-system]
|
||||||
requires = ["poetry-core"]
|
requires = ["poetry-core"]
|
||||||
|
15
src/karkas_blocks/karkas_blocks/standard/chats/__init__.py
Normal file
15
src/karkas_blocks/karkas_blocks/standard/chats/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from karkas_core.modules_system.public_api import (
|
||||||
|
get_module,
|
||||||
|
register_outer_message_middleware,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .main import ChatsMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
def module_init():
|
||||||
|
register_app_config = get_module("standard.database", "register_app_config")
|
||||||
|
from .db import APP_CONFIG
|
||||||
|
|
||||||
|
register_app_config(APP_CONFIG)
|
||||||
|
|
||||||
|
register_outer_message_middleware(ChatsMiddleware())
|
@ -0,0 +1 @@
|
|||||||
|
from .piccolo_app import APP_CONFIG
|
@ -0,0 +1,15 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from karkas_piccolo.conf.apps import AppConfig
|
||||||
|
|
||||||
|
from .tables import ChatInfo
|
||||||
|
|
||||||
|
CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
APP_CONFIG = AppConfig(
|
||||||
|
app_name="standard.chats",
|
||||||
|
migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "piccolo_migrations"),
|
||||||
|
table_classes=[ChatInfo],
|
||||||
|
migration_dependencies=[],
|
||||||
|
commands=[],
|
||||||
|
)
|
@ -0,0 +1,104 @@
|
|||||||
|
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
|
||||||
|
from piccolo.columns.column_types import Date, Integer, Text
|
||||||
|
from piccolo.columns.defaults.date import DateNow
|
||||||
|
from piccolo.columns.indexes import IndexMethod
|
||||||
|
|
||||||
|
ID = "2024-08-20T17:25:21:296396"
|
||||||
|
VERSION = "1.16.0"
|
||||||
|
DESCRIPTION = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def forwards():
|
||||||
|
manager = MigrationManager(
|
||||||
|
migration_id=ID, app_name="standard.chats", description=DESCRIPTION
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(
|
||||||
|
class_name="ChatInfo", tablename="chat_info", schema=None, columns=None
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatInfo",
|
||||||
|
tablename="chat_info",
|
||||||
|
column_name="chat_id",
|
||||||
|
db_column_name="chat_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": True,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatInfo",
|
||||||
|
tablename="chat_info",
|
||||||
|
column_name="chat_name",
|
||||||
|
db_column_name="chat_name",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatInfo",
|
||||||
|
tablename="chat_info",
|
||||||
|
column_name="chat_type",
|
||||||
|
db_column_name="chat_type",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 10,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatInfo",
|
||||||
|
tablename="chat_info",
|
||||||
|
column_name="created_at",
|
||||||
|
db_column_name="created_at",
|
||||||
|
column_class_name="Date",
|
||||||
|
column_class=Date,
|
||||||
|
params={
|
||||||
|
"default": DateNow(),
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return manager
|
@ -0,0 +1,9 @@
|
|||||||
|
from piccolo.columns import Date, Integer, Text
|
||||||
|
from piccolo.table import Table
|
||||||
|
|
||||||
|
|
||||||
|
class ChatInfo(Table):
|
||||||
|
chat_id = Integer(primary_key=True)
|
||||||
|
chat_name = Text()
|
||||||
|
chat_type = Integer(default=10)
|
||||||
|
created_at = Date()
|
13
src/karkas_blocks/karkas_blocks/standard/chats/info.json
Normal file
13
src/karkas_blocks/karkas_blocks/standard/chats/info.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "standard.chats",
|
||||||
|
"name": "Чаты",
|
||||||
|
"description": "Очень полезный модуль",
|
||||||
|
"author": "Karkas Team",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"privileged": true,
|
||||||
|
"dependencies": {
|
||||||
|
"required": {
|
||||||
|
"standard.database": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/karkas_blocks/karkas_blocks/standard/chats/main.py
Normal file
34
src/karkas_blocks/karkas_blocks/standard/chats/main.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from typing import Any, Awaitable, Callable, Dict
|
||||||
|
|
||||||
|
from aiogram import BaseMiddleware
|
||||||
|
from aiogram.types import Chat, TelegramObject
|
||||||
|
|
||||||
|
from .db.tables import ChatInfo
|
||||||
|
|
||||||
|
|
||||||
|
async def update_chat_info(chat: Chat):
|
||||||
|
chat_name = chat.title if chat.type != "private" else ""
|
||||||
|
|
||||||
|
await ChatInfo.insert(
|
||||||
|
ChatInfo(
|
||||||
|
chat_name=chat_name,
|
||||||
|
)
|
||||||
|
).on_conflict(
|
||||||
|
action="DO UPDATE",
|
||||||
|
values=[
|
||||||
|
ChatInfo.chat_name,
|
||||||
|
],
|
||||||
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
class ChatsMiddleware(BaseMiddleware):
|
||||||
|
async def __call__(
|
||||||
|
self,
|
||||||
|
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
|
||||||
|
event: TelegramObject,
|
||||||
|
data: Dict[str, Any],
|
||||||
|
) -> Any:
|
||||||
|
chat = event.chat
|
||||||
|
await update_chat_info(chat)
|
||||||
|
result = await handler(event, data)
|
||||||
|
return result
|
@ -1,48 +0,0 @@
|
|||||||
## Модуль DataBase
|
|
||||||
|
|
||||||
Модуль DataBase предназначен для ведения и работы с базами данных Karkas.
|
|
||||||
|
|
||||||
Модуль содержит в себе следующие таблицы:
|
|
||||||
|
|
||||||
* `Chats` - таблица для хранения информации о чатах.
|
|
||||||
* `Users` - таблица для хранения информации о пользователях.
|
|
||||||
* `Messages` - таблица для хранения информации о сообщениях.
|
|
||||||
* `ChatStats` - таблица для хранения статистики чатов по дням.
|
|
||||||
* `UserStats` - таблица для хранения статистики пользователей по дням.
|
|
||||||
|
|
||||||
Cтруктура таблицы `Chats`:
|
|
||||||
* `chat_id` - идентификатор чата.
|
|
||||||
* `chat_name` - название чата.
|
|
||||||
* `chat_type` - тип чата. (0 - Чат администраторов, 1 - Пользовательский чат, 3 - Чат разрешённых личных запросов к боту
|
|
||||||
10 - Не инициализированный чат)
|
|
||||||
* `chat_stats` - количество всех отправленных сообщений в чате.
|
|
||||||
|
|
||||||
Cтруктура таблицы `Users`:
|
|
||||||
* `user_id` - идентификатор пользователя telegram.
|
|
||||||
* `user_tag` - тег пользователя telegram.
|
|
||||||
* `user_name` - имя пользователя telegram.
|
|
||||||
* `user_role` - роль пользователя в чате. (0 - Администратор, 1 - Модератор, 2 - Пользователь)
|
|
||||||
* `user_stats` - количество всех отправленных сообщений пользователем.
|
|
||||||
* `user_rep` - репутация пользователя.
|
|
||||||
|
|
||||||
Cтруктура таблицы `Messages`:
|
|
||||||
* `message_chat_id` - идентификатор чата в котором отправлено сообщение.
|
|
||||||
* `message_id` - идентификатор сообщения.
|
|
||||||
* `messag_sender_id` - идентификатор пользователя отправившего сообщение. Если сообщение отправил бот, то
|
|
||||||
`messag_sender_id` = 0.
|
|
||||||
* `answer_to_message_id` - идентификатор сообщения на которое дан ответ. Если ответа нет или ответ на служебное
|
|
||||||
сообщение о создании топика в чатах с форумным типом, то `answer_to_message_id` = 0.
|
|
||||||
* `message_ai_model` - идентификатор модели нейросети, которая использовалась для генерации ответа. Если ответ'
|
|
||||||
сгенерирован не был, то `message_ai_model` = null.
|
|
||||||
* `message_text` - текст сообщения.
|
|
||||||
|
|
||||||
Cтруктура таблицы `ChatStats`:
|
|
||||||
* `chat_id` - идентификатор чата для которого собрана статистика.
|
|
||||||
* `date` - дата на которую собрана статистика.
|
|
||||||
* `messages_count` - количество сообщений отправленных в чат за день.
|
|
||||||
|
|
||||||
Cтруктура таблицы `UserStats`:
|
|
||||||
* `chat_id` - идентификатор чата для которого собрана статистика.
|
|
||||||
* `user_id` - идентификатор пользователя для которого собрана статистика.
|
|
||||||
* `date` - дата на которую собрана статистика.
|
|
||||||
* `messages_count` - количество сообщений отправленных пользователем в чат за день.
|
|
@ -1,5 +1 @@
|
|||||||
from . import db_api, models, repositories
|
from .main import module_init, module_late_init, register_app_config
|
||||||
|
|
||||||
|
|
||||||
async def module_init():
|
|
||||||
db_api.connect_database()
|
|
||||||
|
@ -1,301 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
from aiogram.types import Message
|
|
||||||
|
|
||||||
from .exceptions import NotExpectedModuleName
|
|
||||||
from .models.chat_stats import ChatStats
|
|
||||||
from .models.chats import Chats
|
|
||||||
from .models.db import database_proxy
|
|
||||||
from .models.fsm_data import FSMData
|
|
||||||
from .models.messages import Messages
|
|
||||||
from .models.user_stats import UserStats
|
|
||||||
from .models.users import Users
|
|
||||||
|
|
||||||
|
|
||||||
def connect_database(is_test: bool = False, module: str | None = None):
|
|
||||||
if module:
|
|
||||||
raise NotExpectedModuleName()
|
|
||||||
db_path = "database"
|
|
||||||
|
|
||||||
database = pw.SqliteDatabase(f"{db_path}/Karkas.db")
|
|
||||||
database_proxy.initialize(database)
|
|
||||||
database.connect()
|
|
||||||
create_tables(database)
|
|
||||||
|
|
||||||
return database, f"{db_path}/Karkas.db"
|
|
||||||
|
|
||||||
|
|
||||||
def create_tables(db: pw.SqliteDatabase):
|
|
||||||
"""Создание таблиц"""
|
|
||||||
for table in Chats, Messages, Users, UserStats, ChatStats, FSMData:
|
|
||||||
if not table.table_exists():
|
|
||||||
db.create_tables([table])
|
|
||||||
|
|
||||||
|
|
||||||
def add_chat(chat_id, chat_name, chat_type=10, chat_stats=0):
|
|
||||||
chat, created = Chats.get_or_create(
|
|
||||||
id=chat_id,
|
|
||||||
defaults={
|
|
||||||
"chat_name": chat_name,
|
|
||||||
"chat_type": chat_type,
|
|
||||||
"chat_all_stat": chat_stats,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if not created:
|
|
||||||
# Обновить существующий чат, если он уже существует
|
|
||||||
chat.chat_name = chat_name
|
|
||||||
chat.chat_type = chat_type
|
|
||||||
chat.chat_stats = chat_stats
|
|
||||||
chat.save()
|
|
||||||
|
|
||||||
|
|
||||||
def add_user(
|
|
||||||
user_id,
|
|
||||||
user_first_name,
|
|
||||||
user_last_name=None,
|
|
||||||
user_tag=None,
|
|
||||||
user_role=0,
|
|
||||||
user_stats=0,
|
|
||||||
user_rep=0,
|
|
||||||
):
|
|
||||||
if user_last_name is None:
|
|
||||||
user_name = user_first_name
|
|
||||||
else:
|
|
||||||
user_name = user_first_name + " " + user_last_name
|
|
||||||
|
|
||||||
user, created = Users.get_or_create(
|
|
||||||
id=user_id,
|
|
||||||
defaults={
|
|
||||||
"user_tag": user_tag,
|
|
||||||
"user_name": user_name,
|
|
||||||
"user_role": user_role,
|
|
||||||
"user_stats": user_stats,
|
|
||||||
"user_rep": user_rep,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
if not created:
|
|
||||||
# Обновить существующего пользователя, если он уже существует
|
|
||||||
user.user_tag = user_tag
|
|
||||||
user.user_name = user_name
|
|
||||||
user.user_role = user_role
|
|
||||||
user.user_stats = user_stats
|
|
||||||
user.user_rep = user_rep
|
|
||||||
user.save()
|
|
||||||
|
|
||||||
|
|
||||||
def add_message(message: Message, message_ai_model=None):
|
|
||||||
if message.reply_to_message:
|
|
||||||
answer_to_message_id = message.reply_to_message.message_id
|
|
||||||
else:
|
|
||||||
answer_to_message_id = None
|
|
||||||
Messages.create(
|
|
||||||
message_chat_id=message.chat.id,
|
|
||||||
message_id=message.message_id,
|
|
||||||
message_sender_id=message.from_user.id,
|
|
||||||
answer_to_message_id=answer_to_message_id,
|
|
||||||
message_ai_model=message_ai_model,
|
|
||||||
message_text=message.text,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def add_chat_stats(chat_id, date, messages_count):
|
|
||||||
ChatStats.create(chat_id=chat_id, date=date, messages_count=messages_count)
|
|
||||||
|
|
||||||
|
|
||||||
def add_user_stats(chat_id, user_id, date, messages_count):
|
|
||||||
UserStats.create(
|
|
||||||
chat_id=chat_id, user_id=user_id, date=date, messages_count=messages_count
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Работа с таблицей чатов
|
|
||||||
|
|
||||||
|
|
||||||
def get_chat(chat_id):
|
|
||||||
return Chats.get_or_none(Chats.id == chat_id)
|
|
||||||
|
|
||||||
|
|
||||||
def change_chat_name(chat_id, new_chat_name):
|
|
||||||
query = Chats.update(chat_name=new_chat_name).where(Chats.id == chat_id)
|
|
||||||
query.execute()
|
|
||||||
|
|
||||||
|
|
||||||
def change_chat_type(chat_id, new_chat_type):
|
|
||||||
query = Chats.update(chat_type=new_chat_type).where(Chats.id == chat_id)
|
|
||||||
query.execute()
|
|
||||||
|
|
||||||
|
|
||||||
def get_chat_all_stat(chat_id):
|
|
||||||
chat = Chats.get_or_none(Chats.id == chat_id)
|
|
||||||
return chat.chat_all_stat if chat else None
|
|
||||||
|
|
||||||
|
|
||||||
# Работа с таблицей пользователей
|
|
||||||
|
|
||||||
|
|
||||||
def get_user(user_id) -> Users | None:
|
|
||||||
return Users.get_or_none(Users.id == user_id)
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_tag(user_id):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
return user.user_tag if user else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_id(user_tag):
|
|
||||||
user = Users.get_or_none(Users.user_tag == user_tag)
|
|
||||||
return user.id if user else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_name(user_id):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
return user.user_name if user else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_role(user_id: str):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
return user.user_role if user else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_all_stats(user_id):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
return user.user_stats if user else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_rep(user_id):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
return user.user_rep if user else None
|
|
||||||
|
|
||||||
|
|
||||||
def change_user_name(user_id, user_first_name, user_last_name=None):
|
|
||||||
if user_last_name is None:
|
|
||||||
new_user_name = user_first_name
|
|
||||||
else:
|
|
||||||
new_user_name = user_first_name + " " + user_last_name
|
|
||||||
query = Users.update(user_name=new_user_name).where(Users.id == user_id)
|
|
||||||
query.execute()
|
|
||||||
|
|
||||||
|
|
||||||
def change_user_tag(user_id, new_user_tag):
|
|
||||||
query = Users.update(user_tag=new_user_tag).where(Users.id == user_id)
|
|
||||||
query.execute()
|
|
||||||
|
|
||||||
|
|
||||||
def change_user_role(user_id, new_user_role):
|
|
||||||
query = Users.update(user_role=new_user_role).where(Users.id == user_id)
|
|
||||||
query.execute()
|
|
||||||
|
|
||||||
|
|
||||||
# Работа с таблицей сообщений
|
|
||||||
|
|
||||||
|
|
||||||
def get_message(message_chat_id, message_id):
|
|
||||||
return Messages.get_or_none(
|
|
||||||
Messages.message_chat_id == message_chat_id,
|
|
||||||
Messages.message_id == message_id,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def get_message_sender_id(message_chat_id, message_id):
|
|
||||||
message = Messages.get_or_none(
|
|
||||||
Messages.message_chat_id == message_chat_id, Messages.message_id == message_id
|
|
||||||
)
|
|
||||||
return message.message_sender_id if message else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_message_text(message_chat_id, message_id):
|
|
||||||
message = Messages.get_or_none(
|
|
||||||
Messages.message_chat_id == message_chat_id, Messages.message_id == message_id
|
|
||||||
)
|
|
||||||
return message.message_text if message else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_message_ai_model(message_chat_id, message_id):
|
|
||||||
message = Messages.get_or_none(
|
|
||||||
Messages.message_chat_id == message_chat_id, Messages.message_id == message_id
|
|
||||||
)
|
|
||||||
return message.message_ai_model if message else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_answer_to_message_id(message_chat_id, message_id):
|
|
||||||
message = Messages.get_or_none(
|
|
||||||
Messages.message_chat_id == message_chat_id, Messages.message_id == message_id
|
|
||||||
)
|
|
||||||
return message.answer_to_message_id if message else None
|
|
||||||
|
|
||||||
|
|
||||||
# Работа с таблицей статистики чатов
|
|
||||||
|
|
||||||
|
|
||||||
def get_chat_stats(chat_id):
|
|
||||||
chat_stats = {}
|
|
||||||
for chat_stat in ChatStats.select().where(ChatStats.chat_id == chat_id):
|
|
||||||
chat_stats[chat_stat.date] = chat_stat.messages_count
|
|
||||||
return chat_stats
|
|
||||||
|
|
||||||
|
|
||||||
# Работа с таблицей статистики пользователей
|
|
||||||
|
|
||||||
|
|
||||||
def get_user_stats(user_id):
|
|
||||||
user_stats = {}
|
|
||||||
for user_stat in UserStats.select().where(UserStats.user_id == user_id):
|
|
||||||
user_stats[user_stat.date] = user_stat.messages_count
|
|
||||||
return user_stats
|
|
||||||
|
|
||||||
|
|
||||||
# Функции обновления
|
|
||||||
|
|
||||||
|
|
||||||
def update_chat_all_stat(chat_id):
|
|
||||||
query = Chats.update(chat_all_stat=Chats.chat_all_stat + 1).where(
|
|
||||||
Chats.id == chat_id
|
|
||||||
)
|
|
||||||
query.execute()
|
|
||||||
|
|
||||||
|
|
||||||
def update_chat_stats(chat_id, date):
|
|
||||||
chat_stats = ChatStats.get_or_none(
|
|
||||||
ChatStats.chat_id == chat_id, ChatStats.date == date
|
|
||||||
)
|
|
||||||
if chat_stats:
|
|
||||||
query = ChatStats.update(messages_count=ChatStats.messages_count + 1).where(
|
|
||||||
ChatStats.chat_id == chat_id, ChatStats.date == date
|
|
||||||
)
|
|
||||||
query.execute()
|
|
||||||
else:
|
|
||||||
ChatStats.create(chat_id=chat_id, date=date, messages_count=1)
|
|
||||||
|
|
||||||
|
|
||||||
def update_user_all_stat(user_id):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
if user:
|
|
||||||
query = Users.update(user_stats=Users.user_stats + 1).where(Users.id == user_id)
|
|
||||||
query.execute()
|
|
||||||
else:
|
|
||||||
Users.create(id=user_id, user_stats=1)
|
|
||||||
|
|
||||||
|
|
||||||
def update_user_rep(user_id):
|
|
||||||
user = Users.get_or_none(Users.id == user_id)
|
|
||||||
if user:
|
|
||||||
query = Users.update(user_rep=Users.user_rep + 1).where(Users.id == user_id)
|
|
||||||
query.execute()
|
|
||||||
else:
|
|
||||||
Users.create(id=user_id, user_rep=1)
|
|
||||||
|
|
||||||
|
|
||||||
def update_user_stats(chat_id, user_id, date):
|
|
||||||
user_stats = UserStats.get_or_none(
|
|
||||||
UserStats.chat_id == chat_id,
|
|
||||||
UserStats.user_id == user_id,
|
|
||||||
UserStats.date == date,
|
|
||||||
)
|
|
||||||
if user_stats:
|
|
||||||
query = UserStats.update(messages_count=UserStats.messages_count + 1).where(
|
|
||||||
UserStats.chat_id == chat_id,
|
|
||||||
UserStats.user_id == user_id,
|
|
||||||
UserStats.date == date,
|
|
||||||
)
|
|
||||||
query.execute()
|
|
||||||
else:
|
|
||||||
UserStats.create(chat_id=chat_id, user_id=user_id, date=date, messages_count=1)
|
|
@ -1,12 +0,0 @@
|
|||||||
class MissingModuleName(BaseException):
|
|
||||||
def __init__(self):
|
|
||||||
self.message = "Пропущено название директории модуля"
|
|
||||||
|
|
||||||
super().__init__(self.message)
|
|
||||||
|
|
||||||
|
|
||||||
class NotExpectedModuleName(BaseException):
|
|
||||||
def __init__(self):
|
|
||||||
self.message = "Не ожидалось название директории модуля"
|
|
||||||
|
|
||||||
super().__init__(self.message)
|
|
40
src/karkas_blocks/karkas_blocks/standard/database/main.py
Normal file
40
src/karkas_blocks/karkas_blocks/standard/database/main.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from karkas_piccolo.karkas import migrate_forward # isort:skip
|
||||||
|
from karkas_piccolo.conf.apps import AppConfig, AppRegistry # isort:skip
|
||||||
|
|
||||||
|
from piccolo.conf.apps import PiccoloConfModule
|
||||||
|
from piccolo.engine.sqlite import SQLiteEngine
|
||||||
|
|
||||||
|
from karkas_core.singleton import Singleton
|
||||||
|
|
||||||
|
# from karkas_piccolo.conf.apps import A
|
||||||
|
|
||||||
|
|
||||||
|
APPS_CONFIGS = dict()
|
||||||
|
|
||||||
|
|
||||||
|
def register_app_config(app_config: AppConfig):
|
||||||
|
APPS_CONFIGS[app_config.app_name] = app_config
|
||||||
|
|
||||||
|
|
||||||
|
def module_init():
|
||||||
|
singleton = Singleton()
|
||||||
|
singleton.storage["_database"] = dict()
|
||||||
|
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
async def module_late_init():
|
||||||
|
singleton = Singleton()
|
||||||
|
DB = SQLiteEngine(path="./db.sqlite3")
|
||||||
|
|
||||||
|
APP_REGISTRY = AppRegistry(apps_configs=APPS_CONFIGS)
|
||||||
|
|
||||||
|
module = PiccoloConfModule(name="standard.database")
|
||||||
|
module.DB = DB
|
||||||
|
module.APP_REGISTRY = APP_REGISTRY
|
||||||
|
|
||||||
|
singleton.storage["_database"]["conf"] = module
|
||||||
|
|
||||||
|
await migrate_forward()
|
||||||
|
|
||||||
|
pass
|
@ -1 +0,0 @@
|
|||||||
from .fsm_data import FSMData
|
|
@ -1,12 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
|
|
||||||
from .db import database_proxy
|
|
||||||
|
|
||||||
|
|
||||||
class ChatStats(pw.Model):
|
|
||||||
class Meta:
|
|
||||||
database = database_proxy
|
|
||||||
|
|
||||||
chat_id = pw.IntegerField(null=False)
|
|
||||||
date = pw.DateField(null=False)
|
|
||||||
messages_count = pw.IntegerField(null=False, default=0)
|
|
@ -1,12 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
|
|
||||||
from .db import database_proxy
|
|
||||||
|
|
||||||
|
|
||||||
class Chats(pw.Model):
|
|
||||||
class Meta:
|
|
||||||
database = database_proxy
|
|
||||||
|
|
||||||
chat_name = pw.CharField(null=False)
|
|
||||||
chat_type = pw.IntegerField(null=False, default=10)
|
|
||||||
chat_all_stat = pw.IntegerField(null=False)
|
|
@ -1,3 +0,0 @@
|
|||||||
from peewee import DatabaseProxy
|
|
||||||
|
|
||||||
database_proxy = DatabaseProxy()
|
|
@ -1,12 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
|
|
||||||
from .db import database_proxy
|
|
||||||
|
|
||||||
|
|
||||||
class FSMData(pw.Model):
|
|
||||||
class Meta:
|
|
||||||
database = database_proxy
|
|
||||||
|
|
||||||
key = pw.CharField(primary_key=True)
|
|
||||||
state = pw.CharField(null=True)
|
|
||||||
data = pw.CharField(null=True)
|
|
@ -1,15 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
|
|
||||||
from .db import database_proxy
|
|
||||||
|
|
||||||
|
|
||||||
class Messages(pw.Model):
|
|
||||||
class Meta:
|
|
||||||
database = database_proxy
|
|
||||||
|
|
||||||
message_chat_id = pw.IntegerField(null=False)
|
|
||||||
message_id = pw.IntegerField(null=False)
|
|
||||||
message_sender_id = pw.IntegerField(null=False)
|
|
||||||
answer_to_message_id = pw.IntegerField(null=True)
|
|
||||||
message_ai_model = pw.TextField(null=True)
|
|
||||||
message_text = pw.TextField(null=False)
|
|
@ -1,13 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
|
|
||||||
from .db import database_proxy
|
|
||||||
|
|
||||||
|
|
||||||
class UserStats(pw.Model):
|
|
||||||
class Meta:
|
|
||||||
database = database_proxy
|
|
||||||
|
|
||||||
chat_id = pw.IntegerField(null=False)
|
|
||||||
user_id = pw.IntegerField(null=False)
|
|
||||||
date = pw.DateField(null=False)
|
|
||||||
messages_count = pw.IntegerField(null=False, default=0)
|
|
@ -1,14 +0,0 @@
|
|||||||
import peewee as pw
|
|
||||||
|
|
||||||
from .db import database_proxy
|
|
||||||
|
|
||||||
|
|
||||||
class Users(pw.Model):
|
|
||||||
class Meta:
|
|
||||||
database = database_proxy
|
|
||||||
|
|
||||||
user_tag = pw.CharField(null=True)
|
|
||||||
user_name = pw.CharField(null=False) # до 255 символов
|
|
||||||
user_role = pw.IntegerField(null=True, default=3)
|
|
||||||
user_stats = pw.IntegerField(null=True, default=0)
|
|
||||||
user_rep = pw.IntegerField(null=True, default=0)
|
|
@ -1 +0,0 @@
|
|||||||
from .fsm_data import FSMDataRepository
|
|
@ -1,32 +0,0 @@
|
|||||||
from peewee import fn
|
|
||||||
|
|
||||||
from ..models import FSMData
|
|
||||||
|
|
||||||
|
|
||||||
class FSMDataRepository:
|
|
||||||
def get(self, key: str):
|
|
||||||
return FSMData.get_or_none(key=key)
|
|
||||||
|
|
||||||
def set_state(self, key: str, state: str):
|
|
||||||
FSMData.insert(
|
|
||||||
key=key,
|
|
||||||
state=state,
|
|
||||||
data=fn.COALESCE(
|
|
||||||
FSMData.select(FSMData.data).where(FSMData.key == key), None
|
|
||||||
),
|
|
||||||
).on_conflict(
|
|
||||||
conflict_target=[FSMData.key],
|
|
||||||
update={FSMData.state: state},
|
|
||||||
).execute()
|
|
||||||
|
|
||||||
def set_data(self, key: str, data: str):
|
|
||||||
FSMData.insert(
|
|
||||||
key=key,
|
|
||||||
data=data,
|
|
||||||
state=fn.COALESCE(
|
|
||||||
FSMData.select(FSMData.state).where(FSMData.key == key), None
|
|
||||||
),
|
|
||||||
).on_conflict(
|
|
||||||
conflict_target=[FSMData.key],
|
|
||||||
update={FSMData.data: data},
|
|
||||||
).execute()
|
|
@ -1 +0,0 @@
|
|||||||
Эта директория для тестовой БД
|
|
@ -1,142 +0,0 @@
|
|||||||
# flake8: noqa
|
|
||||||
|
|
||||||
import os
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from ...exceptions.module_exceptions import MissingModuleName, NotExpectedModuleName
|
|
||||||
from ..db_api import *
|
|
||||||
|
|
||||||
|
|
||||||
class TestDatabaseAPI(unittest.TestCase):
|
|
||||||
database = None
|
|
||||||
path = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setUpClass(cls):
|
|
||||||
cls.database, cls.path = connect_database(is_test=True, module="database")
|
|
||||||
create_tables(cls.database)
|
|
||||||
|
|
||||||
def test_fail_connect(cls):
|
|
||||||
with cls.assertRaises(MissingModuleName):
|
|
||||||
cls.database, cls.path = connect_database(is_test=True)
|
|
||||||
|
|
||||||
with cls.assertRaises(NotExpectedModuleName):
|
|
||||||
cls.database, cls.path = connect_database(module="database")
|
|
||||||
|
|
||||||
def test_add_and_get_chat(self):
|
|
||||||
add_chat(chat_id=21, chat_role=0, chat_stats=0, chat_federation=0)
|
|
||||||
add_chat(chat_id=22, chat_role=1, chat_stats=100, chat_federation=1)
|
|
||||||
|
|
||||||
chat1 = get_chat(21)
|
|
||||||
self.assertIsNotNone(chat1)
|
|
||||||
self.assertEqual(chat1.id, 21)
|
|
||||||
self.assertEqual(chat1.chat_role, 0)
|
|
||||||
|
|
||||||
chat2 = get_chat(22)
|
|
||||||
self.assertIsNotNone(chat2)
|
|
||||||
self.assertEqual(chat2.id, 22)
|
|
||||||
self.assertEqual(chat2.chat_role, 1)
|
|
||||||
|
|
||||||
def test_add_and_get_message(self):
|
|
||||||
add_message(
|
|
||||||
message_id=1, message_text="Test Message 1", message_sender=1, answer_id=2
|
|
||||||
)
|
|
||||||
add_message(
|
|
||||||
message_id=2, message_text="Test Message 2", message_sender=2, answer_id=1
|
|
||||||
)
|
|
||||||
|
|
||||||
message1 = get_message(1)
|
|
||||||
self.assertIsNotNone(message1)
|
|
||||||
self.assertEqual(message1.id, 1)
|
|
||||||
self.assertEqual(message1.message_text, "Test Message 1")
|
|
||||||
|
|
||||||
message2 = get_message(2)
|
|
||||||
self.assertIsNotNone(message2)
|
|
||||||
self.assertEqual(message2.id, 2)
|
|
||||||
self.assertEqual(message2.message_text, "Test Message 2")
|
|
||||||
|
|
||||||
def test_add_and_get_user(self):
|
|
||||||
add_user(
|
|
||||||
user_id=100,
|
|
||||||
user_name="TestUser1",
|
|
||||||
user_tag="TestTag1",
|
|
||||||
user_role=0,
|
|
||||||
user_stats=10,
|
|
||||||
user_rep=5,
|
|
||||||
)
|
|
||||||
add_user(
|
|
||||||
user_id=101,
|
|
||||||
user_name="TestUser2",
|
|
||||||
user_tag="TestTag2",
|
|
||||||
user_role=1,
|
|
||||||
user_stats=20,
|
|
||||||
user_rep=10,
|
|
||||||
)
|
|
||||||
|
|
||||||
user1 = get_user(100)
|
|
||||||
self.assertIsNotNone(user1)
|
|
||||||
self.assertEqual(user1.id, 100)
|
|
||||||
self.assertEqual(user1.user_name, "TestUser1")
|
|
||||||
|
|
||||||
user2 = get_user(101)
|
|
||||||
self.assertIsNotNone(user2)
|
|
||||||
self.assertEqual(user2.id, 101)
|
|
||||||
self.assertEqual(user2.user_name, "TestUser2")
|
|
||||||
|
|
||||||
def test_get_user_role(self):
|
|
||||||
add_user(
|
|
||||||
user_id=102,
|
|
||||||
user_name="TestUser3",
|
|
||||||
user_tag="TestTag3",
|
|
||||||
user_role=0,
|
|
||||||
user_stats=30,
|
|
||||||
user_rep=15,
|
|
||||||
)
|
|
||||||
add_user(
|
|
||||||
user_id=103,
|
|
||||||
user_name="TestUser4",
|
|
||||||
user_tag="TestTag4",
|
|
||||||
user_role=1,
|
|
||||||
user_stats=40,
|
|
||||||
user_rep=20,
|
|
||||||
)
|
|
||||||
|
|
||||||
user_role1 = get_user_role(102)
|
|
||||||
self.assertEqual(user_role1, 0)
|
|
||||||
|
|
||||||
user_role2 = get_user_role(103)
|
|
||||||
self.assertEqual(user_role2, 1)
|
|
||||||
|
|
||||||
def test_change_user_name(self):
|
|
||||||
add_user(
|
|
||||||
user_id=104,
|
|
||||||
user_name="OldName1",
|
|
||||||
user_tag="TestTag5",
|
|
||||||
user_role=0,
|
|
||||||
user_stats=50,
|
|
||||||
user_rep=25,
|
|
||||||
)
|
|
||||||
change_user_name(104, "NewName1")
|
|
||||||
updated_user1 = get_user(104)
|
|
||||||
self.assertEqual(updated_user1.user_name, "NewName1")
|
|
||||||
|
|
||||||
add_user(
|
|
||||||
user_id=105,
|
|
||||||
user_name="OldName2",
|
|
||||||
user_tag="TestTag6",
|
|
||||||
user_role=1,
|
|
||||||
user_stats=60,
|
|
||||||
user_rep=30,
|
|
||||||
)
|
|
||||||
change_user_name(105, "NewName2")
|
|
||||||
updated_user2 = get_user(105)
|
|
||||||
self.assertEqual(updated_user2.user_name, "NewName2")
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def tearDownClass(cls):
|
|
||||||
cls.database.close()
|
|
||||||
os.system(f"rm {cls.path}") # nosec
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
unittest.main()
|
|
@ -1,11 +1,14 @@
|
|||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Dict
|
||||||
|
|
||||||
from aiogram import Bot
|
from aiogram import BaseMiddleware, Bot
|
||||||
from aiogram.filters import BaseFilter
|
from aiogram.filters import BaseFilter
|
||||||
from aiogram.types import Message
|
from aiogram.types import Message, TelegramObject
|
||||||
from typing_extensions import deprecated
|
from typing_extensions import deprecated
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module
|
from karkas_core.modules_system.public_api import (
|
||||||
|
get_module,
|
||||||
|
register_outer_message_middleware,
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
@ -22,11 +25,47 @@ except Exception:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class GlobalFilter(BaseMiddleware):
|
||||||
|
def __init__(self) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.filter = ChatIDFilter()
|
||||||
|
|
||||||
|
async def __call__(
|
||||||
|
self,
|
||||||
|
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
|
||||||
|
event: TelegramObject,
|
||||||
|
data: Dict[str, Any],
|
||||||
|
) -> Any:
|
||||||
|
if not isinstance(event, Message):
|
||||||
|
return await handler(event, data)
|
||||||
|
|
||||||
|
if not config.get("filters::global::enabled"):
|
||||||
|
return await handler(event, data)
|
||||||
|
|
||||||
|
if await self.filter(event, None):
|
||||||
|
return await handler(event, data)
|
||||||
|
|
||||||
|
if event.chat.type == "private":
|
||||||
|
if config.get("filters::global::private_allowed"):
|
||||||
|
return await handler(event, data)
|
||||||
|
|
||||||
|
return await event.answer(config.get("filters::global::forbidden_message"))
|
||||||
|
|
||||||
|
|
||||||
def module_init():
|
def module_init():
|
||||||
config.register(
|
config.register(
|
||||||
"filters::approved_chat_id", "int", multiple=True, shared=True, default_value=[]
|
"filters::approved_chat_id", "int", multiple=True, shared=True, default_value=[]
|
||||||
)
|
)
|
||||||
config.register("filters::default_chat_tag", "string", shared=True)
|
config.register("filters::default_chat_tag", "string", shared=True)
|
||||||
|
config.register(
|
||||||
|
"filters::global::forbidden_message",
|
||||||
|
"string",
|
||||||
|
default_value="Вы не имеете доступа!",
|
||||||
|
)
|
||||||
|
config.register("filters::global::enabled", "boolean", default_value=False)
|
||||||
|
config.register("filters::global::private_allowed", "boolean", default_value=False)
|
||||||
|
|
||||||
|
register_outer_message_middleware(GlobalFilter())
|
||||||
|
|
||||||
|
|
||||||
def get_approved_chat_id() -> list:
|
def get_approved_chat_id() -> list:
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
from .piccolo_app import APP_CONFIG
|
@ -0,0 +1,15 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from karkas_piccolo.conf.apps import AppConfig
|
||||||
|
|
||||||
|
from .tables import FSMData
|
||||||
|
|
||||||
|
CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
APP_CONFIG = AppConfig(
|
||||||
|
app_name="standard.fsm_database_storage",
|
||||||
|
migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "piccolo_migrations"),
|
||||||
|
table_classes=[FSMData],
|
||||||
|
migration_dependencies=[],
|
||||||
|
commands=[],
|
||||||
|
)
|
@ -0,0 +1,85 @@
|
|||||||
|
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
|
||||||
|
from piccolo.columns.column_types import Text
|
||||||
|
from piccolo.columns.indexes import IndexMethod
|
||||||
|
|
||||||
|
ID = "2024-08-20T15:07:25:276545"
|
||||||
|
VERSION = "1.16.0"
|
||||||
|
DESCRIPTION = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def forwards():
|
||||||
|
manager = MigrationManager(
|
||||||
|
migration_id=ID,
|
||||||
|
app_name="standard.fsm_database_storage",
|
||||||
|
description=DESCRIPTION,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(
|
||||||
|
class_name="FSMData", tablename="fsm_data", schema=None, columns=None
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="FSMData",
|
||||||
|
tablename="fsm_data",
|
||||||
|
column_name="key",
|
||||||
|
db_column_name="key",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"primary": True,
|
||||||
|
"default": "",
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="FSMData",
|
||||||
|
tablename="fsm_data",
|
||||||
|
column_name="state",
|
||||||
|
db_column_name="state",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": True,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="FSMData",
|
||||||
|
tablename="fsm_data",
|
||||||
|
column_name="data",
|
||||||
|
db_column_name="data",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": True,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return manager
|
@ -0,0 +1,8 @@
|
|||||||
|
from piccolo.columns import Text
|
||||||
|
from piccolo.table import Table
|
||||||
|
|
||||||
|
|
||||||
|
class FSMData(Table):
|
||||||
|
key = Text(primary=True)
|
||||||
|
state = Text(null=True)
|
||||||
|
data = Text(null=True)
|
@ -1,5 +1,5 @@
|
|||||||
import json
|
import json
|
||||||
from typing import TYPE_CHECKING, Any, Dict, Optional
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from aiogram.fsm.state import State
|
from aiogram.fsm.state import State
|
||||||
from aiogram.fsm.storage.base import BaseStorage, StorageKey
|
from aiogram.fsm.storage.base import BaseStorage, StorageKey
|
||||||
@ -7,14 +7,54 @@ from aiogram.fsm.storage.base import BaseStorage, StorageKey
|
|||||||
from karkas_core.modules_system.public_api import get_module, log
|
from karkas_core.modules_system.public_api import get_module, log
|
||||||
from karkas_core.modules_system.public_api.public_api import set_fsm
|
from karkas_core.modules_system.public_api.public_api import set_fsm
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
from .db.tables import FSMData
|
||||||
from karkas_blocks.standard.database.repositories import (
|
|
||||||
FSMDataRepository as IFSMDataRepository,
|
|
||||||
|
class FSMDataRepository:
|
||||||
|
def get(self, key: str):
|
||||||
|
return FSMData.select().where(FSMData.key == key).first().run_sync()
|
||||||
|
|
||||||
|
def set_state(self, key: str, state: str):
|
||||||
|
returning = (
|
||||||
|
FSMData.update(
|
||||||
|
{
|
||||||
|
FSMData.state: state,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.where(FSMData.key == key)
|
||||||
|
.returning(FSMData.key)
|
||||||
|
.run_sync()
|
||||||
)
|
)
|
||||||
|
|
||||||
FSMDataRepository: "type[IFSMDataRepository]" = get_module(
|
if len(returning) == 0:
|
||||||
"standard.database", "repositories.FSMDataRepository"
|
FSMData.insert(
|
||||||
|
FSMData(
|
||||||
|
key=key,
|
||||||
|
state=state,
|
||||||
|
data=None,
|
||||||
)
|
)
|
||||||
|
).run_sync()
|
||||||
|
|
||||||
|
def set_data(self, key: str, data: str):
|
||||||
|
returning = (
|
||||||
|
FSMData.update(
|
||||||
|
{
|
||||||
|
FSMData.data: data,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.where(FSMData.key == key)
|
||||||
|
.returning(FSMData.key)
|
||||||
|
.run_sync()
|
||||||
|
)
|
||||||
|
|
||||||
|
if len(returning) == 0:
|
||||||
|
FSMData.insert(
|
||||||
|
FSMData(
|
||||||
|
key=key,
|
||||||
|
data=data,
|
||||||
|
state=None,
|
||||||
|
)
|
||||||
|
).run_sync()
|
||||||
|
|
||||||
|
|
||||||
def serialize_key(key: StorageKey) -> str:
|
def serialize_key(key: StorageKey) -> str:
|
||||||
@ -68,7 +108,7 @@ class SQLStorage(BaseStorage):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
s_state = self.repo.get(s_key)
|
s_state = self.repo.get(s_key)
|
||||||
return s_state.state if s_state else None
|
return s_state["state"] if s_state else None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f"FSM Storage database error: {e}")
|
log(f"FSM Storage database error: {e}")
|
||||||
return None
|
return None
|
||||||
@ -99,7 +139,7 @@ class SQLStorage(BaseStorage):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
s_data = self.repo.get(s_key)
|
s_data = self.repo.get(s_key)
|
||||||
return deserialize_object(s_data.data) if s_data else None
|
return deserialize_object(s_data["data"]) if s_data else None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
log(f"FSM Storage database error: {e}")
|
log(f"FSM Storage database error: {e}")
|
||||||
return None
|
return None
|
||||||
@ -126,4 +166,9 @@ class SQLStorage(BaseStorage):
|
|||||||
|
|
||||||
|
|
||||||
async def module_init():
|
async def module_init():
|
||||||
|
register_app_config = get_module("standard.database", "register_app_config")
|
||||||
|
from .db import APP_CONFIG
|
||||||
|
|
||||||
|
register_app_config(APP_CONFIG)
|
||||||
|
|
||||||
set_fsm(SQLStorage())
|
set_fsm(SQLStorage())
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
from .handlers import get_chat_info, get_user_info
|
from .handlers import get_user_info
|
||||||
from .main import module_init
|
from .main import module_init
|
||||||
|
@ -20,32 +20,10 @@ Roles: "type[IRoles]" = get_module("standard.roles", "Roles")
|
|||||||
|
|
||||||
|
|
||||||
async def get_info_answer_by_id(message: Message, bot: Bot, user_id: int):
|
async def get_info_answer_by_id(message: Message, bot: Bot, user_id: int):
|
||||||
ai_model = db_api.get_message_ai_model(message.chat.id, message.message_id)
|
|
||||||
if ai_model is not None:
|
|
||||||
await message.reply(
|
|
||||||
"Это сообщение было сгенерировано ботом используя модель: " + ai_model
|
|
||||||
)
|
|
||||||
return
|
|
||||||
|
|
||||||
if user_id == bot.id:
|
|
||||||
await message.reply("Это сообщение было отправлено ботом")
|
|
||||||
return
|
|
||||||
|
|
||||||
user = db_api.get_user(user_id)
|
|
||||||
|
|
||||||
if user is None:
|
|
||||||
await message.reply("Пользователь не найден")
|
|
||||||
log(f"Пользователь не найден: {user_id}, {user}")
|
|
||||||
return
|
|
||||||
|
|
||||||
roles = Roles()
|
roles = Roles()
|
||||||
answer = (
|
role = roles.get_user_role(user_id)
|
||||||
f"Пользователь: {user.user_name}\n"
|
|
||||||
f"Роль: {await roles.get_role_name(role_id=user.user_role)}\n"
|
answer = f"Имя: {user_id}\n" f"Роль: {role}\n"
|
||||||
f"Тег: @{user.user_tag}\n"
|
|
||||||
f"Кол-во сообщений: {user.user_stats}\n"
|
|
||||||
f"Репутация: {user.user_rep}"
|
|
||||||
)
|
|
||||||
await message.reply(answer)
|
await message.reply(answer)
|
||||||
|
|
||||||
|
|
||||||
@ -54,14 +32,7 @@ async def get_user_info(message: Message, bot: Bot):
|
|||||||
# Если сообщение отвечает на другое сообщение, то выводим информацию о пользователе, на чье сообщение был ответ
|
# Если сообщение отвечает на другое сообщение, то выводим информацию о пользователе, на чье сообщение был ответ
|
||||||
# Если это бот то выводим информацию, что это бот и какая модель yandexgpt используется
|
# Если это бот то выводим информацию, что это бот и какая модель yandexgpt используется
|
||||||
try:
|
try:
|
||||||
if len(message.text.split()) > 1 and message.text.split()[1].startswith("@"):
|
if message.reply_to_message:
|
||||||
user_tag = message.text.split()[1][1:]
|
|
||||||
user_id = db_api.get_user_id(user_tag)
|
|
||||||
if user_id:
|
|
||||||
await get_info_answer_by_id(message, bot, user_id)
|
|
||||||
else:
|
|
||||||
await message.reply(f"Пользователь с тегом @{user_tag} не найден")
|
|
||||||
elif message.reply_to_message:
|
|
||||||
user_id = message.reply_to_message.from_user.id
|
user_id = message.reply_to_message.from_user.id
|
||||||
await get_info_answer_by_id(message, bot, user_id)
|
await get_info_answer_by_id(message, bot, user_id)
|
||||||
else:
|
else:
|
||||||
|
@ -3,7 +3,7 @@ from aiogram.filters import Command
|
|||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module, register_router
|
from karkas_core.modules_system.public_api import get_module, register_router
|
||||||
|
|
||||||
from .handlers import get_chat_info, get_user_info
|
from .handlers import get_user_info
|
||||||
|
|
||||||
register_command = get_module("standard.command_helper", "register_command")
|
register_command = get_module("standard.command_helper", "register_command")
|
||||||
|
|
||||||
@ -12,9 +12,9 @@ async def module_init():
|
|||||||
router = Router()
|
router = Router()
|
||||||
|
|
||||||
router.message.register(get_user_info, Command("info"))
|
router.message.register(get_user_info, Command("info"))
|
||||||
router.message.register(get_chat_info, Command("chatinfo"))
|
# router.message.register(get_chat_info, Command("chatinfo"))
|
||||||
|
|
||||||
register_router(router)
|
register_router(router)
|
||||||
|
|
||||||
register_command("info", "Информация о пользователе")
|
register_command("info", "Информация о пользователе")
|
||||||
register_command("chatinfo", "Информация о чате")
|
# register_command("chatinfo", "Информация о чате")
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
# Модуль Message Processing
|
|
||||||
|
|
||||||
Модуль `message_processing` обрабатывает все входящие сообщения.
|
|
||||||
|
|
||||||
## Функциональность
|
|
||||||
|
|
||||||
- Проверка чата и пользователя на наличие в базе данных.
|
|
||||||
- Обновление информации о чате и пользователе.
|
|
||||||
- Добавление статистики сообщений.
|
|
||||||
- Передача сообщения модулю `yandexgpt`, если оно соответствует условиям.
|
|
||||||
|
|
||||||
## Использование
|
|
||||||
|
|
||||||
Модуль автоматически обрабатывает все входящие сообщения.
|
|
@ -1 +0,0 @@
|
|||||||
from .message_api import module_init
|
|
@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"id": "standard.message_processing",
|
|
||||||
"name": "Info",
|
|
||||||
"description": "Модуль с информацией",
|
|
||||||
"author": "Karkas Team",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"privileged": false,
|
|
||||||
"dependencies": {
|
|
||||||
"required": {
|
|
||||||
"standard.roles": "^1.0.0",
|
|
||||||
"standard.database": "^1.0.0",
|
|
||||||
"standard.command_helper": "^1.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,155 +0,0 @@
|
|||||||
# flake8: noqa
|
|
||||||
|
|
||||||
from typing import TYPE_CHECKING
|
|
||||||
|
|
||||||
from aiogram import Bot, F, Router, types
|
|
||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module, log, register_router
|
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
|
||||||
from karkas_blocks.standard.config import IConfig
|
|
||||||
|
|
||||||
config: "IConfig" = get_module("standard.config", "config")
|
|
||||||
|
|
||||||
|
|
||||||
def get_yandexgpt_start_words():
|
|
||||||
return config.get("yandexgpt::startword").split(" | ")
|
|
||||||
|
|
||||||
|
|
||||||
def get_yandexgpt_in_words():
|
|
||||||
return config.get("yandexgpt::inword").split(" | ")
|
|
||||||
|
|
||||||
|
|
||||||
chat_not_in_approve = get_module("standard.filters", ["chat_not_in_approve"])
|
|
||||||
|
|
||||||
answer_to_message = get_module("external.yandexgpt", "answer_to_message")
|
|
||||||
|
|
||||||
(
|
|
||||||
get_chat,
|
|
||||||
add_chat,
|
|
||||||
get_user,
|
|
||||||
add_user,
|
|
||||||
get_user_name,
|
|
||||||
change_user_name,
|
|
||||||
get_user_tag,
|
|
||||||
change_user_tag,
|
|
||||||
update_chat_all_stat,
|
|
||||||
update_user_all_stat,
|
|
||||||
add_message,
|
|
||||||
) = get_module(
|
|
||||||
"standard.database",
|
|
||||||
[
|
|
||||||
"db_api.get_chat",
|
|
||||||
"db_api.add_chat",
|
|
||||||
"db_api.get_user",
|
|
||||||
"db_api.add_user",
|
|
||||||
"db_api.get_user_name",
|
|
||||||
"db_api.change_user_name",
|
|
||||||
"db_api.get_user_tag",
|
|
||||||
"db_api.change_user_tag",
|
|
||||||
"db_api.update_chat_all_stat",
|
|
||||||
"db_api.update_user_all_stat",
|
|
||||||
"db_api.add_message",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
async def chat_check(message: types.Message):
|
|
||||||
# Проверка наличия id чата в базе данных чатов
|
|
||||||
# Если чата нет в базе данных, то проверяем его в наличии в конфиге и если он там есть то добавляем его в БД
|
|
||||||
# Если чат есть в базе данных, то pass
|
|
||||||
if get_chat(message.chat.id) is None:
|
|
||||||
if not chat_not_in_approve(message):
|
|
||||||
# print(f"Chat in approve list: {message.chat.id} {message.chat.title}")
|
|
||||||
log(f"Chat in approve list: {message.chat.id} {message.chat.title}")
|
|
||||||
add_chat(message.chat.id, message.chat.title)
|
|
||||||
# print(f"Chat added: {message.chat.id} {message.chat.title}")
|
|
||||||
log(f"Chat added: {message.chat.id} {message.chat.title}")
|
|
||||||
else:
|
|
||||||
# print(f"Chat not in approve list: {message.chat.id} {message.chat.title}")
|
|
||||||
log(f"Chat not in approve list: {message.chat.id} {message.chat.title}")
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
# Проверяем обновление названия чата
|
|
||||||
chat = get_chat(message.chat.id)
|
|
||||||
if chat.chat_name != message.chat.title:
|
|
||||||
chat.chat_name = message.chat.title
|
|
||||||
chat.save()
|
|
||||||
# print(f"Chat updated: {message.chat.id} {message.chat.title}")
|
|
||||||
log(f"Chat updated: {message.chat.id} {message.chat.title}")
|
|
||||||
else:
|
|
||||||
# print(f"Chat already exists: {message.chat.id} {message.chat.title}")
|
|
||||||
log(f"Chat already exists: {message.chat.id} {message.chat.title}")
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def user_check(message: types.Message):
|
|
||||||
# Проверка наличия id пользователя в базе данных пользователей
|
|
||||||
# Если пользователя нет в базе данных, то добавляем его
|
|
||||||
# Если пользователь есть в базе данных, то pass
|
|
||||||
current_user_name = ""
|
|
||||||
if message.from_user.last_name is None:
|
|
||||||
current_user_name = message.from_user.first_name
|
|
||||||
else:
|
|
||||||
current_user_name = (
|
|
||||||
message.from_user.first_name + " " + message.from_user.last_name
|
|
||||||
)
|
|
||||||
|
|
||||||
if get_user(message.from_user.id) is None:
|
|
||||||
add_user(
|
|
||||||
message.from_user.id,
|
|
||||||
message.from_user.first_name,
|
|
||||||
message.from_user.last_name,
|
|
||||||
message.from_user.username,
|
|
||||||
)
|
|
||||||
log(f"User added: {message.from_user.id} {current_user_name}")
|
|
||||||
else:
|
|
||||||
log(
|
|
||||||
f"User already exists: {message.from_user.id} {current_user_name} {message.from_user.username}"
|
|
||||||
)
|
|
||||||
# Проверяем обновление имени пользователя
|
|
||||||
if get_user_name(message.from_user.id) != current_user_name:
|
|
||||||
change_user_name(message.from_user.id, current_user_name)
|
|
||||||
log(f"User name updated: {message.from_user.id} {current_user_name}")
|
|
||||||
# Проверяем обновление username пользователя
|
|
||||||
if get_user_tag(message.from_user.id) != message.from_user.username:
|
|
||||||
change_user_tag(message.from_user.id, message.from_user.username)
|
|
||||||
log(
|
|
||||||
f"User tag updated: {message.from_user.id} {message.from_user.username}"
|
|
||||||
)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
async def add_stats(message: types.Message):
|
|
||||||
# Добавляем пользователю и чату статистику
|
|
||||||
update_chat_all_stat(message.chat.id)
|
|
||||||
update_user_all_stat(message.from_user.id)
|
|
||||||
|
|
||||||
|
|
||||||
async def message_processing(message: types.Message, bot: Bot):
|
|
||||||
await chat_check(message)
|
|
||||||
await user_check(message)
|
|
||||||
await add_stats(message)
|
|
||||||
|
|
||||||
add_message(message)
|
|
||||||
# Если сообщение в начале содержит слово из списка или внутри сообщения содержится слово из списка или сообщение отвечает на сообщение бота
|
|
||||||
|
|
||||||
if (message.text.split(" ")[0] in get_yandexgpt_start_words()) or (
|
|
||||||
any(word in message.text for word in get_yandexgpt_in_words())
|
|
||||||
):
|
|
||||||
log("message_processing")
|
|
||||||
await answer_to_message(message, bot)
|
|
||||||
|
|
||||||
elif message.reply_to_message is not None:
|
|
||||||
if message.reply_to_message.from_user.is_bot:
|
|
||||||
log("message_processing")
|
|
||||||
await answer_to_message(message, bot)
|
|
||||||
|
|
||||||
|
|
||||||
router = Router()
|
|
||||||
# Если сообщение содержит текст то вызывается функция message_processing
|
|
||||||
router.message.register(message_processing, F.text)
|
|
||||||
|
|
||||||
|
|
||||||
async def module_init():
|
|
||||||
register_router(router)
|
|
@ -0,0 +1 @@
|
|||||||
|
from .piccolo_app import APP_CONFIG
|
@ -0,0 +1,15 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from karkas_piccolo.conf.apps import AppConfig
|
||||||
|
|
||||||
|
from .tables import Roles
|
||||||
|
|
||||||
|
CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
APP_CONFIG = AppConfig(
|
||||||
|
app_name="standard.roles",
|
||||||
|
migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "piccolo_migrations"),
|
||||||
|
table_classes=[Roles],
|
||||||
|
migration_dependencies=[],
|
||||||
|
commands=[],
|
||||||
|
)
|
@ -0,0 +1,59 @@
|
|||||||
|
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
|
||||||
|
from piccolo.columns.column_types import Integer
|
||||||
|
from piccolo.columns.indexes import IndexMethod
|
||||||
|
|
||||||
|
ID = "2024-08-20T13:36:02:417372"
|
||||||
|
VERSION = "1.16.0"
|
||||||
|
DESCRIPTION = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def forwards():
|
||||||
|
manager = MigrationManager(
|
||||||
|
migration_id=ID, app_name="standard.roles", description=DESCRIPTION
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(class_name="Roles", tablename="roles", schema=None, columns=None)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Roles",
|
||||||
|
tablename="roles",
|
||||||
|
column_name="role_id",
|
||||||
|
db_column_name="role_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Roles",
|
||||||
|
tablename="roles",
|
||||||
|
column_name="user_id",
|
||||||
|
db_column_name="user_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return manager
|
@ -0,0 +1,7 @@
|
|||||||
|
from piccolo.columns import Integer
|
||||||
|
from piccolo.table import Table
|
||||||
|
|
||||||
|
|
||||||
|
class Roles(Table):
|
||||||
|
role_id = Integer()
|
||||||
|
user_id = Integer()
|
@ -4,6 +4,9 @@ from karkas_core.modules_system.public_api import get_module
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
|
from karkas_blocks.standard.database import (
|
||||||
|
register_app_config as Iregister_app_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def module_init():
|
def module_init():
|
||||||
@ -34,4 +37,12 @@ def module_init():
|
|||||||
visible=False,
|
visible=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
register_app_config: "Iregister_app_config" = get_module(
|
||||||
|
"standard.database", "register_app_config"
|
||||||
|
)
|
||||||
|
|
||||||
|
from .db import APP_CONFIG
|
||||||
|
|
||||||
|
register_app_config(APP_CONFIG)
|
||||||
|
|
||||||
pass
|
pass
|
||||||
|
@ -2,13 +2,11 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from karkas_core.modules_system.public_api import get_module
|
from karkas_core.modules_system.public_api import get_module
|
||||||
|
|
||||||
|
from .db.tables import Roles as RolesTable
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from karkas_blocks.standard.config import IConfig
|
from karkas_blocks.standard.config import IConfig
|
||||||
from karkas_blocks.standard.database.db_api import get_user_role as IGetUserRoleType
|
|
||||||
|
|
||||||
get_user_role: "IGetUserRoleType" = get_module(
|
|
||||||
"standard.database", "db_api.get_user_role"
|
|
||||||
)
|
|
||||||
config: "IConfig" = get_module("standard.config", "config")
|
config: "IConfig" = get_module("standard.config", "config")
|
||||||
|
|
||||||
|
|
||||||
@ -21,6 +19,17 @@ class Roles:
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def get_user_role(self, user_id):
|
||||||
|
row = (
|
||||||
|
RolesTable.select(RolesTable.role_id)
|
||||||
|
.where(RolesTable.user_id == user_id)
|
||||||
|
.first()
|
||||||
|
.run_sync()
|
||||||
|
)
|
||||||
|
if row is not None:
|
||||||
|
return row["role_id"]
|
||||||
|
return None
|
||||||
|
|
||||||
def update_roles(self):
|
def update_roles(self):
|
||||||
self.user_role_id = config.get("roles::user")
|
self.user_role_id = config.get("roles::user")
|
||||||
self.moderator_role_id = config.get("roles::moderator")
|
self.moderator_role_id = config.get("roles::moderator")
|
||||||
@ -29,7 +38,7 @@ class Roles:
|
|||||||
|
|
||||||
async def check_admin_permission(self, user_id):
|
async def check_admin_permission(self, user_id):
|
||||||
self.update_roles()
|
self.update_roles()
|
||||||
match get_user_role(user_id):
|
match self.get_user_role(user_id):
|
||||||
case self.admin_role_id:
|
case self.admin_role_id:
|
||||||
return True
|
return True
|
||||||
case _:
|
case _:
|
||||||
@ -37,7 +46,7 @@ class Roles:
|
|||||||
|
|
||||||
async def check_moderator_permission(self, user_id):
|
async def check_moderator_permission(self, user_id):
|
||||||
self.update_roles()
|
self.update_roles()
|
||||||
match get_user_role(user_id):
|
match self.get_user_role(user_id):
|
||||||
case self.moderator_role_id:
|
case self.moderator_role_id:
|
||||||
return True
|
return True
|
||||||
case _:
|
case _:
|
||||||
@ -59,7 +68,7 @@ class Roles:
|
|||||||
|
|
||||||
async def get_user_permission(self, user_id):
|
async def get_user_permission(self, user_id):
|
||||||
self.update_roles()
|
self.update_roles()
|
||||||
match get_user_role(user_id):
|
match self.get_user_role(user_id):
|
||||||
case self.admin_role_id:
|
case self.admin_role_id:
|
||||||
return self.admin
|
return self.admin
|
||||||
case self.moderator_role_id:
|
case self.moderator_role_id:
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
from karkas_core.modules_system.public_api import (
|
||||||
|
get_module,
|
||||||
|
register_outer_message_middleware,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .main import StatisticsMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
def module_init():
|
||||||
|
register_app_config = get_module("standard.database", "register_app_config")
|
||||||
|
from .db import APP_CONFIG
|
||||||
|
|
||||||
|
register_app_config(APP_CONFIG)
|
||||||
|
|
||||||
|
register_outer_message_middleware(StatisticsMiddleware())
|
@ -0,0 +1 @@
|
|||||||
|
from .piccolo_app import APP_CONFIG
|
@ -0,0 +1,15 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from karkas_piccolo.conf.apps import AppConfig
|
||||||
|
|
||||||
|
from .tables import ChatStats, Messages, UserStats
|
||||||
|
|
||||||
|
CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
APP_CONFIG = AppConfig(
|
||||||
|
app_name="standard.statistics",
|
||||||
|
migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "piccolo_migrations"),
|
||||||
|
table_classes=[ChatStats, Messages, UserStats],
|
||||||
|
migration_dependencies=[],
|
||||||
|
commands=[],
|
||||||
|
)
|
@ -0,0 +1,322 @@
|
|||||||
|
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
|
||||||
|
from piccolo.columns.column_types import Date, Integer, Text
|
||||||
|
from piccolo.columns.defaults.date import DateNow
|
||||||
|
from piccolo.columns.indexes import IndexMethod
|
||||||
|
|
||||||
|
ID = "2024-08-20T16:28:38:371951"
|
||||||
|
VERSION = "1.16.0"
|
||||||
|
DESCRIPTION = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def forwards():
|
||||||
|
manager = MigrationManager(
|
||||||
|
migration_id=ID, app_name="standard.statistics", description=DESCRIPTION
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(
|
||||||
|
class_name="Messages", tablename="messages", schema=None, columns=None
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(
|
||||||
|
class_name="ChatStats", tablename="chat_stats", schema=None, columns=None
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(
|
||||||
|
class_name="UserStats", tablename="user_stats", schema=None, columns=None
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Messages",
|
||||||
|
tablename="messages",
|
||||||
|
column_name="key",
|
||||||
|
db_column_name="key",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": False,
|
||||||
|
"primary_key": True,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Messages",
|
||||||
|
tablename="messages",
|
||||||
|
column_name="chat_id",
|
||||||
|
db_column_name="chat_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Messages",
|
||||||
|
tablename="messages",
|
||||||
|
column_name="message_id",
|
||||||
|
db_column_name="message_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Messages",
|
||||||
|
tablename="messages",
|
||||||
|
column_name="sender_id",
|
||||||
|
db_column_name="sender_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Messages",
|
||||||
|
tablename="messages",
|
||||||
|
column_name="answer_to_message_id",
|
||||||
|
db_column_name="answer_to_message_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": None,
|
||||||
|
"null": True,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="Messages",
|
||||||
|
tablename="messages",
|
||||||
|
column_name="message_text",
|
||||||
|
db_column_name="message_text",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatStats",
|
||||||
|
tablename="chat_stats",
|
||||||
|
column_name="chat_id",
|
||||||
|
db_column_name="chat_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": True,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatStats",
|
||||||
|
tablename="chat_stats",
|
||||||
|
column_name="date",
|
||||||
|
db_column_name="date",
|
||||||
|
column_class_name="Date",
|
||||||
|
column_class=Date,
|
||||||
|
params={
|
||||||
|
"default": DateNow(),
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="ChatStats",
|
||||||
|
tablename="chat_stats",
|
||||||
|
column_name="messages_count",
|
||||||
|
db_column_name="messages_count",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserStats",
|
||||||
|
tablename="user_stats",
|
||||||
|
column_name="key",
|
||||||
|
db_column_name="key",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": False,
|
||||||
|
"primary_key": True,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserStats",
|
||||||
|
tablename="user_stats",
|
||||||
|
column_name="chat_id",
|
||||||
|
db_column_name="chat_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserStats",
|
||||||
|
tablename="user_stats",
|
||||||
|
column_name="user_id",
|
||||||
|
db_column_name="user_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserStats",
|
||||||
|
tablename="user_stats",
|
||||||
|
column_name="date",
|
||||||
|
db_column_name="date",
|
||||||
|
column_class_name="Date",
|
||||||
|
column_class=Date,
|
||||||
|
params={
|
||||||
|
"default": DateNow(),
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserStats",
|
||||||
|
tablename="user_stats",
|
||||||
|
column_name="messages_count",
|
||||||
|
db_column_name="messages_count",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return manager
|
@ -0,0 +1,34 @@
|
|||||||
|
from piccolo.columns import Date, Integer, Text
|
||||||
|
from piccolo.table import Table
|
||||||
|
|
||||||
|
|
||||||
|
class ChatStats(Table):
|
||||||
|
chat_id = Integer(primary_key=True)
|
||||||
|
date = Date()
|
||||||
|
messages_count = Integer(default=0)
|
||||||
|
|
||||||
|
|
||||||
|
class Messages(Table):
|
||||||
|
# Временная мера, пока не примут
|
||||||
|
# https://github.com/piccolo-orm/piccolo/pull/984
|
||||||
|
# {message_chat_id}-{message_id}
|
||||||
|
key = Text(primary_key=True)
|
||||||
|
|
||||||
|
chat_id = Integer()
|
||||||
|
message_id = Integer()
|
||||||
|
sender_id = Integer()
|
||||||
|
answer_to_message_id = Integer(null=True, default=None)
|
||||||
|
# message_ai_model = pw.TextField(null=True)
|
||||||
|
message_text = Text()
|
||||||
|
|
||||||
|
|
||||||
|
class UserStats(Table):
|
||||||
|
# Временная мера, пока не примут
|
||||||
|
# https://github.com/piccolo-orm/piccolo/pull/984
|
||||||
|
# {chat_id}-{user_id}
|
||||||
|
key = Text(primary_key=True)
|
||||||
|
|
||||||
|
chat_id = Integer()
|
||||||
|
user_id = Integer()
|
||||||
|
date = Date()
|
||||||
|
messages_count = Integer(default=0)
|
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"id": "standard.statistics",
|
||||||
|
"name": "Статистика",
|
||||||
|
"description": "Очень полезный модуль",
|
||||||
|
"author": "Karkas Team",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"privileged": true,
|
||||||
|
"dependencies": {
|
||||||
|
"required": {
|
||||||
|
"standard.database": "^1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pythonDependencies": {
|
||||||
|
"required": {
|
||||||
|
"piccolo": "*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
68
src/karkas_blocks/karkas_blocks/standard/statistics/main.py
Normal file
68
src/karkas_blocks/karkas_blocks/standard/statistics/main.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
from typing import Any, Awaitable, Callable, Dict
|
||||||
|
|
||||||
|
from aiogram import BaseMiddleware
|
||||||
|
from aiogram.types import Message, TelegramObject
|
||||||
|
|
||||||
|
from .db.tables import ChatStats, Messages, UserStats
|
||||||
|
|
||||||
|
|
||||||
|
async def update_chat_stats(event: Message):
|
||||||
|
await ChatStats.insert(
|
||||||
|
ChatStats(chat_id=event.chat.id, date=event.date, messages_count=1)
|
||||||
|
).on_conflict(
|
||||||
|
action="DO UPDATE",
|
||||||
|
values=[
|
||||||
|
ChatStats.date,
|
||||||
|
(ChatStats.messages_count, ChatStats.messages_count + 1),
|
||||||
|
],
|
||||||
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
async def update_user_stats(event: Message):
|
||||||
|
await UserStats.insert(
|
||||||
|
UserStats(
|
||||||
|
key=f"{event.chat.id}-{event.from_user.id}",
|
||||||
|
chat_id=event.chat.id,
|
||||||
|
user_id=event.from_user.id,
|
||||||
|
date=event.date,
|
||||||
|
messages_count=1,
|
||||||
|
)
|
||||||
|
).on_conflict(
|
||||||
|
action="DO UPDATE",
|
||||||
|
values=[
|
||||||
|
UserStats.date,
|
||||||
|
(UserStats.messages_count, UserStats.messages_count + 1),
|
||||||
|
],
|
||||||
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
async def save_messages(event: Message):
|
||||||
|
await Messages.insert(
|
||||||
|
Messages(
|
||||||
|
key=f"{event.chat.id}-{event.message_id}",
|
||||||
|
chat_id=event.chat.id,
|
||||||
|
message_id=event.message_id,
|
||||||
|
sender_id=event.from_user.id,
|
||||||
|
answer_to_message_id=(
|
||||||
|
event.reply_to_message.message_id if event.reply_to_message else None
|
||||||
|
),
|
||||||
|
message_text=event.text,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class StatisticsMiddleware(BaseMiddleware):
|
||||||
|
async def __call__(
|
||||||
|
self,
|
||||||
|
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
|
||||||
|
event: TelegramObject,
|
||||||
|
data: Dict[str, Any],
|
||||||
|
) -> Any:
|
||||||
|
|
||||||
|
await update_chat_stats(event)
|
||||||
|
await update_user_stats(event)
|
||||||
|
await save_messages(event)
|
||||||
|
|
||||||
|
result = await handler(event, data)
|
||||||
|
|
||||||
|
return result
|
15
src/karkas_blocks/karkas_blocks/standard/users/__init__.py
Normal file
15
src/karkas_blocks/karkas_blocks/standard/users/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from karkas_core.modules_system.public_api import (
|
||||||
|
get_module,
|
||||||
|
register_outer_message_middleware,
|
||||||
|
)
|
||||||
|
|
||||||
|
from .main import UsersMiddleware
|
||||||
|
|
||||||
|
|
||||||
|
def module_init():
|
||||||
|
register_app_config = get_module("standard.database", "register_app_config")
|
||||||
|
from .db import APP_CONFIG
|
||||||
|
|
||||||
|
register_app_config(APP_CONFIG)
|
||||||
|
|
||||||
|
register_outer_message_middleware(UsersMiddleware())
|
@ -0,0 +1 @@
|
|||||||
|
from .piccolo_app import APP_CONFIG
|
@ -0,0 +1,15 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from karkas_piccolo.conf.apps import AppConfig
|
||||||
|
|
||||||
|
from .tables import UserInfo
|
||||||
|
|
||||||
|
CURRENT_DIRECTORY = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
|
APP_CONFIG = AppConfig(
|
||||||
|
app_name="standard.users",
|
||||||
|
migrations_folder_path=os.path.join(CURRENT_DIRECTORY, "piccolo_migrations"),
|
||||||
|
table_classes=[UserInfo],
|
||||||
|
migration_dependencies=[],
|
||||||
|
commands=[],
|
||||||
|
)
|
@ -0,0 +1,104 @@
|
|||||||
|
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
|
||||||
|
from piccolo.columns.column_types import Date, Integer, Text
|
||||||
|
from piccolo.columns.defaults.date import DateNow
|
||||||
|
from piccolo.columns.indexes import IndexMethod
|
||||||
|
|
||||||
|
ID = "2024-08-20T17:06:44:026509"
|
||||||
|
VERSION = "1.16.0"
|
||||||
|
DESCRIPTION = ""
|
||||||
|
|
||||||
|
|
||||||
|
async def forwards():
|
||||||
|
manager = MigrationManager(
|
||||||
|
migration_id=ID, app_name="standard.users", description=DESCRIPTION
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_table(
|
||||||
|
class_name="UserInfo", tablename="user_info", schema=None, columns=None
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserInfo",
|
||||||
|
tablename="user_info",
|
||||||
|
column_name="user_id",
|
||||||
|
db_column_name="user_id",
|
||||||
|
column_class_name="Integer",
|
||||||
|
column_class=Integer,
|
||||||
|
params={
|
||||||
|
"default": 0,
|
||||||
|
"null": False,
|
||||||
|
"primary_key": True,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserInfo",
|
||||||
|
tablename="user_info",
|
||||||
|
column_name="name",
|
||||||
|
db_column_name="name",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserInfo",
|
||||||
|
tablename="user_info",
|
||||||
|
column_name="tag",
|
||||||
|
db_column_name="tag",
|
||||||
|
column_class_name="Text",
|
||||||
|
column_class=Text,
|
||||||
|
params={
|
||||||
|
"default": "",
|
||||||
|
"null": True,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
manager.add_column(
|
||||||
|
table_class_name="UserInfo",
|
||||||
|
tablename="user_info",
|
||||||
|
column_name="created_at",
|
||||||
|
db_column_name="created_at",
|
||||||
|
column_class_name="Date",
|
||||||
|
column_class=Date,
|
||||||
|
params={
|
||||||
|
"default": DateNow(),
|
||||||
|
"null": False,
|
||||||
|
"primary_key": False,
|
||||||
|
"unique": False,
|
||||||
|
"index": False,
|
||||||
|
"index_method": IndexMethod.btree,
|
||||||
|
"choices": None,
|
||||||
|
"db_column_name": None,
|
||||||
|
"secret": False,
|
||||||
|
},
|
||||||
|
schema=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
return manager
|
@ -0,0 +1,9 @@
|
|||||||
|
from piccolo.columns import Date, Integer, Text
|
||||||
|
from piccolo.table import Table
|
||||||
|
|
||||||
|
|
||||||
|
class UserInfo(Table):
|
||||||
|
user_id = Integer(primary_key=True)
|
||||||
|
name = Text()
|
||||||
|
tag = Text(null=True)
|
||||||
|
created_at = Date()
|
13
src/karkas_blocks/karkas_blocks/standard/users/info.json
Normal file
13
src/karkas_blocks/karkas_blocks/standard/users/info.json
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"id": "standard.users",
|
||||||
|
"name": "Пользователи",
|
||||||
|
"description": "Очень полезный модуль",
|
||||||
|
"author": "Karkas Team",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"privileged": true,
|
||||||
|
"dependencies": {
|
||||||
|
"required": {
|
||||||
|
"standard.database": "^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
36
src/karkas_blocks/karkas_blocks/standard/users/main.py
Normal file
36
src/karkas_blocks/karkas_blocks/standard/users/main.py
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
from typing import Any, Awaitable, Callable, Dict
|
||||||
|
|
||||||
|
from aiogram import BaseMiddleware
|
||||||
|
from aiogram.types import TelegramObject, User
|
||||||
|
|
||||||
|
from .db.tables import UserInfo
|
||||||
|
|
||||||
|
|
||||||
|
async def update_user_info(user: User):
|
||||||
|
if user.last_name is None:
|
||||||
|
user_name = user.first_name
|
||||||
|
else:
|
||||||
|
user_name = user.first_name + " " + user.last_name
|
||||||
|
|
||||||
|
await UserInfo.insert(
|
||||||
|
UserInfo(user_id=user.id, name=user_name, tag=user.username)
|
||||||
|
).on_conflict(
|
||||||
|
action="DO UPDATE",
|
||||||
|
values=[
|
||||||
|
UserInfo.name,
|
||||||
|
UserInfo.tag,
|
||||||
|
],
|
||||||
|
).run()
|
||||||
|
|
||||||
|
|
||||||
|
class UsersMiddleware(BaseMiddleware):
|
||||||
|
async def __call__(
|
||||||
|
self,
|
||||||
|
handler: Callable[[TelegramObject, Dict[str, Any]], Awaitable[Any]],
|
||||||
|
event: TelegramObject,
|
||||||
|
data: Dict[str, Any],
|
||||||
|
) -> Any:
|
||||||
|
user = event.from_user
|
||||||
|
await update_user_info(user)
|
||||||
|
result = await handler(event, data)
|
||||||
|
return result
|
394
src/karkas_blocks/poetry.lock
generated
394
src/karkas_blocks/poetry.lock
generated
@ -13,18 +13,18 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiogram"
|
name = "aiogram"
|
||||||
version = "3.10.0"
|
version = "3.12.0"
|
||||||
description = "Modern and fully asynchronous framework for Telegram Bot API"
|
description = "Modern and fully asynchronous framework for Telegram Bot API"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "aiogram-3.10.0-py3-none-any.whl", hash = "sha256:dc43bfbe68c736cca48d91ffbc55a397df24b56c332206af850965619689beca"},
|
{file = "aiogram-3.12.0-py3-none-any.whl", hash = "sha256:4b9969d6751b810748835d341aafc0b44fe4675d741bff1b07c24daa47edf79f"},
|
||||||
{file = "aiogram-3.10.0.tar.gz", hash = "sha256:f500d4b309e3cc08a87ae5a053b229199034f382925de00aa2ed005d5e25d575"},
|
{file = "aiogram-3.12.0.tar.gz", hash = "sha256:582a5cf058fccc470ed08c9aa36fdef5b708d01965e51963c3969596c1d2ac19"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
aiofiles = ">=23.2.1,<23.3.0"
|
aiofiles = ">=23.2.1,<23.3.0"
|
||||||
aiohttp = ">=3.9.0,<3.10.0"
|
aiohttp = ">=3.9.0,<3.11"
|
||||||
certifi = ">=2023.7.22"
|
certifi = ">=2023.7.22"
|
||||||
magic-filter = ">=1.0.12,<1.1"
|
magic-filter = ">=1.0.12,<1.1"
|
||||||
pydantic = ">=2.4.1,<2.9"
|
pydantic = ">=2.4.1,<2.9"
|
||||||
@ -32,8 +32,8 @@ typing-extensions = ">=4.7.0,<=5.0"
|
|||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cli = ["aiogram-cli (>=1.0.3,<1.1.0)"]
|
cli = ["aiogram-cli (>=1.0.3,<1.1.0)"]
|
||||||
dev = ["black (>=24.4.2,<24.5.0)", "isort (>=5.13.2,<5.14.0)", "motor-types (>=1.0.0b4,<1.1.0)", "mypy (>=1.10.0,<1.11.0)", "packaging (>=24.1,<25.0)", "pre-commit (>=3.5,<4.0)", "ruff (>=0.4.9,<0.5.0)", "toml (>=0.10.2,<0.11.0)"]
|
dev = ["black (>=24.4.2,<24.5.0)", "isort (>=5.13.2,<5.14.0)", "motor-types (>=1.0.0b4,<1.1.0)", "mypy (>=1.10.0,<1.11.0)", "packaging (>=24.1,<25.0)", "pre-commit (>=3.5,<4.0)", "ruff (>=0.5.1,<0.6.0)", "toml (>=0.10.2,<0.11.0)"]
|
||||||
docs = ["furo (>=2023.9.10,<2023.10.0)", "markdown-include (>=0.8.1,<0.9.0)", "pygments (>=2.16.1,<2.17.0)", "pymdown-extensions (>=10.3,<11.0)", "sphinx (>=7.2.6,<7.3.0)", "sphinx-autobuild (>=2021.3.14,<2021.4.0)", "sphinx-copybutton (>=0.5.2,<0.6.0)", "sphinx-intl (>=2.1.0,<2.2.0)", "sphinx-substitution-extensions (>=2022.2.16,<2022.3.0)", "sphinxcontrib-towncrier (>=0.3.2a0,<0.4.0)", "towncrier (>=23.6.0,<23.7.0)"]
|
docs = ["furo (>=2023.9.10,<2023.10.0)", "markdown-include (>=0.8.1,<0.9.0)", "pygments (>=2.16.1,<2.17.0)", "pymdown-extensions (>=10.3,<11.0)", "sphinx (>=7.2.6,<7.3.0)", "sphinx-autobuild (>=2021.3.14,<2021.4.0)", "sphinx-copybutton (>=0.5.2,<0.6.0)", "sphinx-intl (>=2.1.0,<2.2.0)", "sphinx-substitution-extensions (>=2022.2.16,<2022.3.0)", "sphinxcontrib-towncrier (>=0.4.0a0,<0.5.0)", "towncrier (>=24.7.1,<24.8.0)"]
|
||||||
fast = ["aiodns (>=3.0.0)", "uvloop (>=0.17.0)"]
|
fast = ["aiodns (>=3.0.0)", "uvloop (>=0.17.0)"]
|
||||||
i18n = ["babel (>=2.13.0,<2.14.0)"]
|
i18n = ["babel (>=2.13.0,<2.14.0)"]
|
||||||
mongo = ["motor (>=3.3.2,<3.4.0)"]
|
mongo = ["motor (>=3.3.2,<3.4.0)"]
|
||||||
@ -41,100 +41,113 @@ proxy = ["aiohttp-socks (>=0.8.3,<0.9.0)"]
|
|||||||
redis = ["redis[hiredis] (>=5.0.1,<5.1.0)"]
|
redis = ["redis[hiredis] (>=5.0.1,<5.1.0)"]
|
||||||
test = ["aresponses (>=2.1.6,<2.2.0)", "pycryptodomex (>=3.19.0,<3.20.0)", "pytest (>=7.4.2,<7.5.0)", "pytest-aiohttp (>=1.0.5,<1.1.0)", "pytest-asyncio (>=0.21.1,<0.22.0)", "pytest-cov (>=4.1.0,<4.2.0)", "pytest-html (>=4.0.2,<4.1.0)", "pytest-lazy-fixture (>=0.6.3,<0.7.0)", "pytest-mock (>=3.12.0,<3.13.0)", "pytest-mypy (>=0.10.3,<0.11.0)", "pytz (>=2023.3,<2024.0)"]
|
test = ["aresponses (>=2.1.6,<2.2.0)", "pycryptodomex (>=3.19.0,<3.20.0)", "pytest (>=7.4.2,<7.5.0)", "pytest-aiohttp (>=1.0.5,<1.1.0)", "pytest-asyncio (>=0.21.1,<0.22.0)", "pytest-cov (>=4.1.0,<4.2.0)", "pytest-html (>=4.0.2,<4.1.0)", "pytest-lazy-fixture (>=0.6.3,<0.7.0)", "pytest-mock (>=3.12.0,<3.13.0)", "pytest-mypy (>=0.10.3,<0.11.0)", "pytz (>=2023.3,<2024.0)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aiohappyeyeballs"
|
||||||
|
version = "2.4.0"
|
||||||
|
description = "Happy Eyeballs for asyncio"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.8"
|
||||||
|
files = [
|
||||||
|
{file = "aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd"},
|
||||||
|
{file = "aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiohttp"
|
name = "aiohttp"
|
||||||
version = "3.9.5"
|
version = "3.10.4"
|
||||||
description = "Async http client/server framework (asyncio)"
|
description = "Async http client/server framework (asyncio)"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fcde4c397f673fdec23e6b05ebf8d4751314fa7c24f93334bf1f1364c1c69ac7"},
|
{file = "aiohttp-3.10.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:81037ddda8cc0a95c6d8c1b9029d0b19a62db8770c0e239e3bea0109d294ab66"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5d6b3f1fabe465e819aed2c421a6743d8debbde79b6a8600739300630a01bf2c"},
|
{file = "aiohttp-3.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71944d4f4090afc07ce96b7029d5a574240e2f39570450df4af0d5b93a5ee64a"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae79c1bc12c34082d92bf9422764f799aee4746fd7a392db46b7fd357d4a17a"},
|
{file = "aiohttp-3.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c774f08afecc0a617966f45a9c378456e713a999ee60654d9727617def3e4ee4"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d3ebb9e1316ec74277d19c5f482f98cc65a73ccd5430540d6d11682cd857430"},
|
{file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc990e73613c78ab2930b60266135066f37fdfce6b32dd604f42c5c377ee880a"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84dabd95154f43a2ea80deffec9cb44d2e301e38a0c9d331cc4aa0166fe28ae3"},
|
{file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6acd1a908740f708358d240f9a3243cec31a456e3ded65c2cb46f6043bc6735"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8a02fbeca6f63cb1f0475c799679057fc9268b77075ab7cf3f1c600e81dd46b"},
|
{file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6075e27e7e54fbcd1c129c5699b2d251c885c9892e26d59a0fb7705141c2d14b"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c26959ca7b75ff768e2776d8055bf9582a6267e24556bb7f7bd29e677932be72"},
|
{file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc98d93d11d860ac823beb6131f292d82efb76f226b5e28a3eab1ec578dfd041"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:714d4e5231fed4ba2762ed489b4aec07b2b9953cf4ee31e9871caac895a839c0"},
|
{file = "aiohttp-3.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:201ddf1471567568be381b6d4701e266a768f7eaa2f99ef753f2c9c5e1e3fb5c"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7a6a8354f1b62e15d48e04350f13e726fa08b62c3d7b8401c0a1314f02e3558"},
|
{file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7d202ec55e61f06b1a1eaf317fba7546855cbf803c13ce7625d462fb8c88e238"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c413016880e03e69d166efb5a1a95d40f83d5a3a648d16486592c49ffb76d0db"},
|
{file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:96b2e7c110a941c8c1a692703b8ac1013e47f17ee03356c71d55c0a54de2ce38"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ff84aeb864e0fac81f676be9f4685f0527b660f1efdc40dcede3c251ef1e867f"},
|
{file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8ba0fbc56c44883bd757ece433f9caadbca67f565934afe9bc53ba3bd99cc368"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ad7f2919d7dac062f24d6f5fe95d401597fbb015a25771f85e692d043c9d7832"},
|
{file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:46cc9069da466652bb7b8b3fac1f8ce2e12a9dc0fb11551faa420c4cdbc60abf"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:702e2c7c187c1a498a4e2b03155d52658fdd6fda882d3d7fbb891a5cf108bb10"},
|
{file = "aiohttp-3.10.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:93a19cd1e9dc703257fda78b8e889c3a08eabaa09f6ff0d867850b03964f80d1"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-win32.whl", hash = "sha256:67c3119f5ddc7261d47163ed86d760ddf0e625cd6246b4ed852e82159617b5fb"},
|
{file = "aiohttp-3.10.4-cp310-cp310-win32.whl", hash = "sha256:8593040bcc8075fc0e817a602bc5d3d74c7bd717619ffc175a8ba0188edebadf"},
|
||||||
{file = "aiohttp-3.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:471f0ef53ccedec9995287f02caf0c068732f026455f07db3f01a46e49d76bbb"},
|
{file = "aiohttp-3.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:326fb5228aadfc395981d9b336d56a698da335897c4143105c73b583d7500839"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:e0ae53e33ee7476dd3d1132f932eeb39bf6125083820049d06edcdca4381f342"},
|
{file = "aiohttp-3.10.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:dfe48f477e02ef5ab247c6ac431a6109c69b5c24cb3ccbcd3e27c4fb39691fe4"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c088c4d70d21f8ca5c0b8b5403fe84a7bc8e024161febdd4ef04575ef35d474d"},
|
{file = "aiohttp-3.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6fe78b51852e25d4e20be51ef88c2a0bf31432b9f2223bdbd61c01a0f9253a7"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:639d0042b7670222f33b0028de6b4e2fad6451462ce7df2af8aee37dcac55424"},
|
{file = "aiohttp-3.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5cc75ff5efbd92301e63a157fddb18a6964a3f40e31c77d57e97dbb9bb3373b4"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f26383adb94da5e7fb388d441bf09c61e5e35f455a3217bfd790c6b6bc64b2ee"},
|
{file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dca39391f45fbb28daa6412f98c625265bf6b512cc41382df61672d1b242f8f4"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:66331d00fb28dc90aa606d9a54304af76b335ae204d1836f65797d6fe27f1ca2"},
|
{file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8616dd5ed8b3b4029021b560305041c62e080bb28f238c27c2e150abe3539587"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ff550491f5492ab5ed3533e76b8567f4b37bd2995e780a1f46bca2024223233"},
|
{file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d7958ba22854b3f00a7bbb66cde1dc759760ce8a3e6dfe9ea53f06bccaa9aa2"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f22eb3a6c1080d862befa0a89c380b4dafce29dc6cd56083f630073d102eb595"},
|
{file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a24ac7164a824ef2e8e4e9a9f6debb1f43c44ad7ad04efc6018a6610555666d"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a81b1143d42b66ffc40a441379387076243ef7b51019204fd3ec36b9f69e77d6"},
|
{file = "aiohttp-3.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:660ad010b8fd0b26e8edb8ae5c036db5b16baac4278198ad238b11956d920b3d"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f64fd07515dad67f24b6ea4a66ae2876c01031de91c93075b8093f07c0a2d93d"},
|
{file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:93ee83008d3e505db9846a5a1f48a002676d8dcc90ee431a9462541c9b81393c"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:93e22add827447d2e26d67c9ac0161756007f152fdc5210277d00a85f6c92323"},
|
{file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:77071795efd6ba87f409001141fb05c94ee962b9fca6c8fa1f735c2718512de4"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:55b39c8684a46e56ef8c8d24faf02de4a2b2ac60d26cee93bc595651ff545de9"},
|
{file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ff371ae72a1816c3eeba5c9cff42cb739aaa293fec7d78f180d1c7ee342285b6"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4715a9b778f4293b9f8ae7a0a7cef9829f02ff8d6277a39d7f40565c737d3771"},
|
{file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c253e81f12da97f85d45441e8c6da0d9c12e07db4a7136b0a955df6fc5e4bf51"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:afc52b8d969eff14e069a710057d15ab9ac17cd4b6753042c407dcea0e40bf75"},
|
{file = "aiohttp-3.10.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ce101c447cf7ba4b6e5ab07bfa2c0da21cbab66922f78a601f0b84fd7710d72"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-win32.whl", hash = "sha256:b3df71da99c98534be076196791adca8819761f0bf6e08e07fd7da25127150d6"},
|
{file = "aiohttp-3.10.4-cp311-cp311-win32.whl", hash = "sha256:705c311ecf2d30fbcf3570d1a037c657be99095694223488140c47dee4ef2460"},
|
||||||
{file = "aiohttp-3.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:88e311d98cc0bf45b62fc46c66753a83445f5ab20038bcc1b8a1cc05666f428a"},
|
{file = "aiohttp-3.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:ebddbfea8a8d6b97f717658fa85a96681a28990072710d3de3a4eba5d6804a37"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:c7a4b7a6cf5b6eb11e109a9755fd4fda7d57395f8c575e166d363b9fc3ec4678"},
|
{file = "aiohttp-3.10.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fe4d63f42d9c604521b208b754abfafe01218af4a8f6332b43196ee8fe88bbd5"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0a158704edf0abcac8ac371fbb54044f3270bdbc93e254a82b6c82be1ef08f3c"},
|
{file = "aiohttp-3.10.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fef7b7bd3a6911b4d148332136d34d3c2aee3d54d354373b1da6d96bc08089a5"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d153f652a687a8e95ad367a86a61e8d53d528b0530ef382ec5aaf533140ed00f"},
|
{file = "aiohttp-3.10.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fff8606149098935188fe1e135f7e7991e6a36d6fe394fd15939fc57d0aff889"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82a6a97d9771cb48ae16979c3a3a9a18b600a8505b1115cfe354dfb2054468b4"},
|
{file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eb3df1aa83602be9a5e572c834d74c3c8e382208b59a873aabfe4c493c45ed0"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60cdbd56f4cad9f69c35eaac0fbbdf1f77b0ff9456cebd4902f3dd1cf096464c"},
|
{file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c4a71d4a5e0cbfd4bfadd13cb84fe2bc76c64d550dc4f22c22008c9354cffb3"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8676e8fd73141ded15ea586de0b7cda1542960a7b9ad89b2b06428e97125d4fa"},
|
{file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf61884a604c399458c4a42c8caea000fbcc44255ed89577ff50cb688a0fe8e2"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da00da442a0e31f1c69d26d224e1efd3a1ca5bcbf210978a2ca7426dfcae9f58"},
|
{file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2015e4b40bd5dedc8155c2b2d24a2b07963ae02b5772373d0b599a68e38a316b"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18f634d540dd099c262e9f887c8bbacc959847cfe5da7a0e2e1cf3f14dbf2daf"},
|
{file = "aiohttp-3.10.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b06e1a66bf0a1a2d0f12aef25843dfd2093df080d6c1acbc43914bb9c8f36ed3"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:320e8618eda64e19d11bdb3bd04ccc0a816c17eaecb7e4945d01deee2a22f95f"},
|
{file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:eb898c9ad5a1228a669ebe2e2ba3d76aebe1f7c10b78f09a36000254f049fc2b"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:2faa61a904b83142747fc6a6d7ad8fccff898c849123030f8e75d5d967fd4a81"},
|
{file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2d64a5a7539320c3cecb4bca093ea825fcc906f8461cf8b42a7bf3c706ce1932"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:8c64a6dc3fe5db7b1b4d2b5cb84c4f677768bdc340611eca673afb7cf416ef5a"},
|
{file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:438c6e1492d060b21285f4b6675b941cf96dd9ef3dfdd59940561029b82e3e1f"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:393c7aba2b55559ef7ab791c94b44f7482a07bf7640d17b341b79081f5e5cd1a"},
|
{file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e99bf118afb2584848dba169a685fe092b338a4fe52ae08c7243d7bc4cc204fe"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c671dc117c2c21a1ca10c116cfcd6e3e44da7fcde37bf83b2be485ab377b25da"},
|
{file = "aiohttp-3.10.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9dc26781fb95225c6170619dece8b5c6ca7cfb1b0be97b7ee719915773d0c2a9"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-win32.whl", hash = "sha256:5a7ee16aab26e76add4afc45e8f8206c95d1d75540f1039b84a03c3b3800dd59"},
|
{file = "aiohttp-3.10.4-cp312-cp312-win32.whl", hash = "sha256:45bb655cb8b3a61e19977183a4e0962051ae90f6d46588ed4addb8232128141c"},
|
||||||
{file = "aiohttp-3.9.5-cp312-cp312-win_amd64.whl", hash = "sha256:5ca51eadbd67045396bc92a4345d1790b7301c14d1848feaac1d6a6c9289e888"},
|
{file = "aiohttp-3.10.4-cp312-cp312-win_amd64.whl", hash = "sha256:347bbdc48411badc24fe3a13565820bc742db3aa2f9127cd5f48c256caf87e29"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:694d828b5c41255e54bc2dddb51a9f5150b4eefa9886e38b52605a05d96566e8"},
|
{file = "aiohttp-3.10.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:4ad284cee0fdcdc0216346b849fd53d201b510aff3c48aa3622daec9ada4bf80"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0605cc2c0088fcaae79f01c913a38611ad09ba68ff482402d3410bf59039bfb8"},
|
{file = "aiohttp-3.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:58df59234be7d7e80548b9482ebfeafdda21948c25cb2873c7f23870c8053dfe"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4558e5012ee03d2638c681e156461d37b7a113fe13970d438d95d10173d25f78"},
|
{file = "aiohttp-3.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5f52225af7f91f27b633f73473e9ef0aa8e2112d57b69eaf3aa4479e3ea3bc0e"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dbc053ac75ccc63dc3a3cc547b98c7258ec35a215a92bd9f983e0aac95d3d5b"},
|
{file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93f1a0e12c321d923c024b56d7dcd8012e60bf30a4b3fb69a88be15dcb9ab80b"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4109adee842b90671f1b689901b948f347325045c15f46b39797ae1bf17019de"},
|
{file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9e9e9a51dd12f2f71fdbd7f7230dcb75ed8f77d8ac8e07c73b599b6d7027e5c"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6ea1a5b409a85477fd8e5ee6ad8f0e40bf2844c270955e09360418cfd09abac"},
|
{file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:38bb515f1affc36d3d97b02bf82099925a5785c4a96066ff4400a83ad09d3d5d"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3c2890ca8c59ee683fd09adf32321a40fe1cf164e3387799efb2acebf090c11"},
|
{file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e685afb0e3b7b861d89cb3690d89eeda221b43095352efddaaa735c6baf87f3"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3916c8692dbd9d55c523374a3b8213e628424d19116ac4308e434dbf6d95bbdd"},
|
{file = "aiohttp-3.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd5673e3391564871ba6753cf674dcf2051ef19dc508998fe0758a6c7b429a0"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8d1964eb7617907c792ca00b341b5ec3e01ae8c280825deadbbd678447b127e1"},
|
{file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4b34e5086e1ead3baa740e32adf35cc5e42338e44c4b07f7b62b41ca6d6a5bfd"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5ab8e1f6bee051a4bf6195e38a5c13e5e161cb7bad83d8854524798bd9fcd6e"},
|
{file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:c3fd3b8f0164fb2866400cd6eb9e884ab0dc95f882cf8b25e560ace7350c552d"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:52c27110f3862a1afbcb2af4281fc9fdc40327fa286c4625dfee247c3ba90156"},
|
{file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:b95e1694d234f27b4bbf5bdef56bb751974ac5dbe045b1e462bde1fe39421cbe"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:7f64cbd44443e80094309875d4f9c71d0401e966d191c3d469cde4642bc2e031"},
|
{file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:c031de4dfabe7bb6565743745ab43d20588944ddfc7233360169cab4008eee2f"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8b4f72fbb66279624bfe83fd5eb6aea0022dad8eec62b71e7bf63ee1caadeafe"},
|
{file = "aiohttp-3.10.4-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:03c5a3143d4a82c43a3d82ac77d9cdef527a72f1c04dcca7b14770879f33d196"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-win32.whl", hash = "sha256:6380c039ec52866c06d69b5c7aad5478b24ed11696f0e72f6b807cfb261453da"},
|
{file = "aiohttp-3.10.4-cp38-cp38-win32.whl", hash = "sha256:b71722b527445e02168e2d1cf435772731874671a647fa159ad000feea7933b6"},
|
||||||
{file = "aiohttp-3.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:da22dab31d7180f8c3ac7c7635f3bcd53808f374f6aa333fe0b0b9e14b01f91a"},
|
{file = "aiohttp-3.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:0fd1f57aac7d01c9c768675d531976d20d5b79d9da67fac87e55d41b4ade05f9"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:1732102949ff6087589408d76cd6dea656b93c896b011ecafff418c9661dc4ed"},
|
{file = "aiohttp-3.10.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:15b36a644d1f44ea3d94a0bbb71e75d5f394a3135dc388a209466e22b711ce64"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c6021d296318cb6f9414b48e6a439a7f5d1f665464da507e8ff640848ee2a58a"},
|
{file = "aiohttp-3.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:394ddf9d216cf0bd429b223239a0ab628f01a7a1799c93ce4685eedcdd51b9bc"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:239f975589a944eeb1bad26b8b140a59a3a320067fb3cd10b75c3092405a1372"},
|
{file = "aiohttp-3.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dd33f4d571b4143fc9318c3d9256423579c7d183635acc458a6db81919ae5204"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b7b30258348082826d274504fbc7c849959f1989d86c29bc355107accec6cfb"},
|
{file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5991b80886655e6c785aadf3114d4f86e6bec2da436e2bb62892b9f048450a4"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cd2adf5c87ff6d8b277814a28a535b59e20bfea40a101db6b3bdca7e9926bc24"},
|
{file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:92021bf0a4b9ad16851a6c1ca3c86e5b09aecca4f7a2576430c6bbf3114922b1"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a3d838441bebcf5cf442700e3963f58b5c33f015341f9ea86dcd7d503c07e2"},
|
{file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:938e37fd337343c67471098736deb33066d72cec7d8927b9c1b6b4ea807ade9e"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e3a1ae66e3d0c17cf65c08968a5ee3180c5a95920ec2731f53343fac9bad106"},
|
{file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d697023b16c62f9aeb3ffdfb8ec4ac3afd477388993b9164b47dadbd60e7062"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c69e77370cce2d6df5d12b4e12bdcca60c47ba13d1cbbc8645dd005a20b738b"},
|
{file = "aiohttp-3.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c2f9f07fe6d0d51bd2a788cbb339f1570fd691449c53b5dec83ff838f117703e"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0cbf56238f4bbf49dab8c2dc2e6b1b68502b1e88d335bea59b3f5b9f4c001475"},
|
{file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:50ac670f3fc13ce95e4d6d5a299db9288cc84c663aa630142444ef504756fcf7"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d1469f228cd9ffddd396d9948b8c9cd8022b6d1bf1e40c6f25b0fb90b4f893ed"},
|
{file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9bcdd19398212785a9cb82a63a4b75a299998343f3f5732dfd37c1a4275463f9"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:45731330e754f5811c314901cebdf19dd776a44b31927fa4b4dbecab9e457b0c"},
|
{file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:122c26f0976225aba46f381e3cabb5ef89a08af6503fc30493fb732e578cfa55"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:3fcb4046d2904378e3aeea1df51f697b0467f2aac55d232c87ba162709478c46"},
|
{file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:d0665e2a346b6b66959f831ffffd8aa71dd07dd2300017d478f5b47573e66cfe"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8cf142aa6c1a751fcb364158fd710b8a9be874b81889c2bd13aa8893197455e2"},
|
{file = "aiohttp-3.10.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:625a4a9d4b9f80e7bbaaf2ace06341cf701b2fee54232843addf0bb7304597fb"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-win32.whl", hash = "sha256:7b179eea70833c8dee51ec42f3b4097bd6370892fa93f510f76762105568cf09"},
|
{file = "aiohttp-3.10.4-cp39-cp39-win32.whl", hash = "sha256:5115490112f39f16ae87c1b34dff3e2c95306cf456b1d2af5974c4ac7d2d1ec7"},
|
||||||
{file = "aiohttp-3.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:38d80498e2e169bc61418ff36170e0aad0cd268da8b38a17c4cf29d254a8b3f1"},
|
{file = "aiohttp-3.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9b58b2ef7f28a2462ba86acbf3b20371bd80a1faa1cfd82f31968af4ac81ef25"},
|
||||||
{file = "aiohttp-3.9.5.tar.gz", hash = "sha256:edea7d15772ceeb29db4aff55e482d4bcfb6ae160ce144f2682de02f6d693551"},
|
{file = "aiohttp-3.10.4.tar.gz", hash = "sha256:23a5f97e7dd22e181967fb6cb6c3b11653b0fdbbc4bb7739d9b6052890ccab96"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
aiohappyeyeballs = ">=2.3.0"
|
||||||
aiosignal = ">=1.1.2"
|
aiosignal = ">=1.1.2"
|
||||||
|
async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
|
||||||
attrs = ">=17.3.0"
|
attrs = ">=17.3.0"
|
||||||
frozenlist = ">=1.1.1"
|
frozenlist = ">=1.1.1"
|
||||||
multidict = ">=4.5,<7.0"
|
multidict = ">=4.5,<7.0"
|
||||||
yarl = ">=1.0,<2.0"
|
yarl = ">=1.0,<2.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
speedups = ["Brotli", "aiodns", "brotlicffi"]
|
speedups = ["Brotli", "aiodns (>=3.2.0)", "brotlicffi"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiosignal"
|
name = "aiosignal"
|
||||||
@ -161,24 +174,35 @@ files = [
|
|||||||
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-timeout"
|
||||||
|
version = "4.0.3"
|
||||||
|
description = "Timeout context manager for asyncio programs"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
|
||||||
|
{file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
version = "23.2.0"
|
version = "24.2.0"
|
||||||
description = "Classes Without Boilerplate"
|
description = "Classes Without Boilerplate"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
|
{file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
|
||||||
{file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
|
{file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
|
benchmark = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-codspeed", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
||||||
dev = ["attrs[tests]", "pre-commit"]
|
cov = ["cloudpickle", "coverage[toml] (>=5.3)", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
||||||
docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
|
dev = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
||||||
tests = ["attrs[tests-no-zope]", "zope-interface"]
|
docs = ["cogapp", "furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier (<24.7)"]
|
||||||
tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
|
tests = ["cloudpickle", "hypothesis", "mypy (>=1.11.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"]
|
||||||
tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
|
tests-mypy = ["mypy (>=1.11.1)", "pytest-mypy-plugins"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "blinker"
|
name = "blinker"
|
||||||
@ -679,6 +703,29 @@ files = [
|
|||||||
editorconfig = ">=0.12.2"
|
editorconfig = ">=0.12.2"
|
||||||
six = ">=1.13.0"
|
six = ">=1.13.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "karkas-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10,<3.13"
|
||||||
|
files = []
|
||||||
|
develop = true
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
aiogram = "^3.10.0"
|
||||||
|
dataclasses-json = "^0.6.7"
|
||||||
|
restrictedpython = "^7.1"
|
||||||
|
semver = "^3.0.2"
|
||||||
|
setuptools = "^71.0.1"
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
webhook = ["fastapi (>=0.111.1,<0.112.0)", "hypercorn (>=0.17.3,<0.18.0)"]
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "../karkas_core"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "magic-filter"
|
name = "magic-filter"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
@ -783,13 +830,13 @@ tests = ["pytest", "pytz", "simplejson"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "more-itertools"
|
name = "more-itertools"
|
||||||
version = "10.3.0"
|
version = "10.4.0"
|
||||||
description = "More routines for operating on iterables, beyond itertools"
|
description = "More routines for operating on iterables, beyond itertools"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "more-itertools-10.3.0.tar.gz", hash = "sha256:e5d93ef411224fbcef366a6e8ddc4c5781bc6359d43412a65dd5964e46111463"},
|
{file = "more-itertools-10.4.0.tar.gz", hash = "sha256:fe0e63c4ab068eac62410ab05cccca2dc71ec44ba8ef29916a0090df061cf923"},
|
||||||
{file = "more_itertools-10.3.0-py3-none-any.whl", hash = "sha256:ea6a02e24a9161e51faad17a8782b92a0df82c12c1c8886fec7f0c3fa1a1b320"},
|
{file = "more_itertools-10.4.0-py3-none-any.whl", hash = "sha256:0f7d9f83a0a8dcfa8a2694a770590d98a67ea943e3d9f5298309a484758c4e27"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -913,29 +960,6 @@ files = [
|
|||||||
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "karkas-core"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = ""
|
|
||||||
optional = false
|
|
||||||
python-versions = "~3.12"
|
|
||||||
files = []
|
|
||||||
develop = true
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
aiogram = "^3.10.0"
|
|
||||||
dataclasses-json = "^0.6.7"
|
|
||||||
restrictedpython = "^7.1"
|
|
||||||
semver = "^3.0.2"
|
|
||||||
setuptools = "^71.0.1"
|
|
||||||
|
|
||||||
[package.extras]
|
|
||||||
webhook = ["fastapi (>=0.111.1,<0.112.0)", "hypercorn (>=0.17.3,<0.18.0)"]
|
|
||||||
|
|
||||||
[package.source]
|
|
||||||
type = "directory"
|
|
||||||
url = "../karkas_core"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "24.1"
|
version = "24.1"
|
||||||
@ -1094,62 +1118,64 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pyyaml"
|
name = "pyyaml"
|
||||||
version = "6.0.1"
|
version = "6.0.2"
|
||||||
description = "YAML parser and emitter for Python"
|
description = "YAML parser and emitter for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
|
{file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
|
{file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
|
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
|
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
|
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
|
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
|
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
|
||||||
{file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
|
{file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
|
{file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
|
{file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
|
{file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
|
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
|
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
|
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
|
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
|
||||||
{file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
|
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
|
{file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
|
{file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"},
|
{file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
|
{file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
|
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
|
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
|
||||||
{file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
|
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
|
||||||
{file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
|
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
|
||||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
|
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
|
||||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
|
{file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
|
||||||
{file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
|
{file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
|
||||||
{file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
|
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
|
||||||
{file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
|
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
|
||||||
{file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
|
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
|
||||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
|
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
|
||||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
|
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
|
||||||
{file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
|
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
|
||||||
{file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
|
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
|
||||||
{file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
|
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
|
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
|
{file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
|
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
|
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
|
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
|
{file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
|
||||||
{file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
|
{file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
|
{file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
|
{file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
|
{file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
|
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
|
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
|
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
|
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
|
||||||
{file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
|
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
|
||||||
{file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
|
{file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
|
||||||
|
{file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
|
||||||
|
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1175,13 +1201,13 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "restrictedpython"
|
name = "restrictedpython"
|
||||||
version = "7.1"
|
version = "7.2"
|
||||||
description = "RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment."
|
description = "RestrictedPython is a defined subset of the Python language which allows to provide a program input into a trusted environment."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7, <3.13"
|
python-versions = "<3.13,>=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "RestrictedPython-7.1-py3-none-any.whl", hash = "sha256:56d0c73e5de1757702053383601b0fcd3fb2e428039ee1df860409ad67b17d2b"},
|
{file = "RestrictedPython-7.2-py3-none-any.whl", hash = "sha256:139cb41da6e57521745a566d05825f7a09e6a884f7fa922568cff0a70b84ce6b"},
|
||||||
{file = "RestrictedPython-7.1.tar.gz", hash = "sha256:875aeb51c139d78e34cef8605dc65309b449168060dd08551a1fe9edb47cb9a5"},
|
{file = "RestrictedPython-7.2.tar.gz", hash = "sha256:4d1d30f709a6621ca7c4236f08b67b732a651c8099145f137078c7dd4bed3d21"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -1268,13 +1294,13 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tenacity"
|
name = "tenacity"
|
||||||
version = "8.5.0"
|
version = "9.0.0"
|
||||||
description = "Retry code until it succeeds"
|
description = "Retry code until it succeeds"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "tenacity-8.5.0-py3-none-any.whl", hash = "sha256:b594c2a5945830c267ce6b79a166228323ed52718f30302c1359836112346687"},
|
{file = "tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539"},
|
||||||
{file = "tenacity-8.5.0.tar.gz", hash = "sha256:8bc6c0c8a09b31e6cad13c47afbed1a567518250a9a171418582ed8d9c20ca78"},
|
{file = "tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -1446,13 +1472,13 @@ multidict = ">=4.0"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
version = "3.19.2"
|
version = "3.20.0"
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "zipp-3.19.2-py3-none-any.whl", hash = "sha256:f091755f667055f2d02b32c53771a7a6c8b47e1fdbc4b72a8b9072b3eef8015c"},
|
{file = "zipp-3.20.0-py3-none-any.whl", hash = "sha256:58da6168be89f0be59beb194da1250516fdaa062ccebd30127ac65d30045e10d"},
|
||||||
{file = "zipp-3.19.2.tar.gz", hash = "sha256:bf1dcf6450f873a13e952a29504887c89e6de7506209e5b1bcc3460135d4de19"},
|
{file = "zipp-3.20.0.tar.gz", hash = "sha256:0145e43d89664cfe1a2e533adc75adafed82fe2da404b4bbb6b026c0157bdb31"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -1461,5 +1487,5 @@ test = ["big-O", "importlib-resources", "jaraco.functools", "jaraco.itertools",
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "~3.12"
|
python-versions = ">=3.10,<3.13"
|
||||||
content-hash = "c7fd9c49b3d382a9bbd3c75c20d668574e671a7f1e6aca5ee1e1787059a9e1e7"
|
content-hash = "fa282851d0e8d13e428df402edeffe56b4468295b93e492135a6d73760ffb9a5"
|
||||||
|
@ -6,7 +6,7 @@ authors = ["Maxim Slipenko <maxim@slipenko.com>"]
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.10,<=3.12"
|
python = ">=3.10,<3.13"
|
||||||
karkas-core = { path = "../karkas_core", develop = true }
|
karkas-core = { path = "../karkas_core", develop = true }
|
||||||
|
|
||||||
peewee = "^3.17.6"
|
peewee = "^3.17.6"
|
||||||
|
@ -3,8 +3,7 @@ from typing import TYPE_CHECKING
|
|||||||
|
|
||||||
from aiogram import Bot, Dispatcher
|
from aiogram import Bot, Dispatcher
|
||||||
|
|
||||||
from karkas_core.lib import register_bot_webhook
|
from karkas_core.logger import log, setup_logger
|
||||||
from karkas_core.logger import CustomLogger, log, setup_logger
|
|
||||||
from karkas_core.modules_system import ModulesManager
|
from karkas_core.modules_system import ModulesManager
|
||||||
from karkas_core.modules_system.public_api import get_module
|
from karkas_core.modules_system.public_api import get_module
|
||||||
from karkas_core.singleton import Singleton
|
from karkas_core.singleton import Singleton
|
||||||
@ -70,6 +69,9 @@ class Karkas:
|
|||||||
from fastapi import FastAPI
|
from fastapi import FastAPI
|
||||||
from hypercorn.asyncio import serve
|
from hypercorn.asyncio import serve
|
||||||
from hypercorn.config import Config as HyperConfig
|
from hypercorn.config import Config as HyperConfig
|
||||||
|
|
||||||
|
from karkas_core.lib import register_bot_webhook
|
||||||
|
from karkas_core.logger import CustomLogger
|
||||||
except ImportError:
|
except ImportError:
|
||||||
log(
|
log(
|
||||||
"Error: FastAPI and Hypercorn are required"
|
"Error: FastAPI and Hypercorn are required"
|
||||||
|
@ -22,4 +22,5 @@ class Singleton(metaclass=SingletonMeta):
|
|||||||
"_fsm_storage": MemoryStorage(),
|
"_fsm_storage": MemoryStorage(),
|
||||||
"_routers": [],
|
"_routers": [],
|
||||||
"_outer_message_middlewares": [],
|
"_outer_message_middlewares": [],
|
||||||
|
"metainfo": {},
|
||||||
}
|
}
|
||||||
|
104
src/karkas_core/poetry.lock
generated
104
src/karkas_core/poetry.lock
generated
@ -128,6 +128,7 @@ files = [
|
|||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
aiosignal = ">=1.1.2"
|
aiosignal = ">=1.1.2"
|
||||||
|
async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""}
|
||||||
attrs = ">=17.3.0"
|
attrs = ">=17.3.0"
|
||||||
frozenlist = ">=1.1.1"
|
frozenlist = ">=1.1.1"
|
||||||
multidict = ">=4.5,<7.0"
|
multidict = ">=4.5,<7.0"
|
||||||
@ -173,14 +174,27 @@ files = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
|
||||||
idna = ">=2.8"
|
idna = ">=2.8"
|
||||||
sniffio = ">=1.1"
|
sniffio = ">=1.1"
|
||||||
|
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
||||||
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
|
||||||
trio = ["trio (>=0.23)"]
|
trio = ["trio (>=0.23)"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-timeout"
|
||||||
|
version = "4.0.3"
|
||||||
|
description = "Timeout context manager for asyncio programs"
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"},
|
||||||
|
{file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "attrs"
|
name = "attrs"
|
||||||
version = "23.2.0"
|
version = "23.2.0"
|
||||||
@ -539,6 +553,20 @@ files = [
|
|||||||
dnspython = ">=2.0.0"
|
dnspython = ">=2.0.0"
|
||||||
idna = ">=2.0.0"
|
idna = ">=2.0.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "exceptiongroup"
|
||||||
|
version = "1.2.2"
|
||||||
|
description = "Backport of PEP 654 (exception groups)"
|
||||||
|
optional = true
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
|
||||||
|
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.extras]
|
||||||
|
test = ["pytest (>=6)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fastapi"
|
name = "fastapi"
|
||||||
version = "0.111.1"
|
version = "0.111.1"
|
||||||
@ -846,9 +874,13 @@ files = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
exceptiongroup = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
||||||
h11 = "*"
|
h11 = "*"
|
||||||
h2 = ">=3.1.0"
|
h2 = ">=3.1.0"
|
||||||
priority = "*"
|
priority = "*"
|
||||||
|
taskgroup = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
|
tomli = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
|
typing_extensions = {version = "*", markers = "python_version < \"3.11\""}
|
||||||
wsproto = ">=0.14.0"
|
wsproto = ">=0.14.0"
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
@ -940,6 +972,27 @@ files = [
|
|||||||
editorconfig = ">=0.12.2"
|
editorconfig = ">=0.12.2"
|
||||||
six = ">=1.13.0"
|
six = ">=1.13.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "karkas-blocks"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
optional = false
|
||||||
|
python-versions = ">=3.10,<3.13"
|
||||||
|
files = []
|
||||||
|
develop = true
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
dash = "^2.17.1"
|
||||||
|
dash-bootstrap-components = "^1.6.0"
|
||||||
|
dash-extensions = "^1.0.18"
|
||||||
|
karkas-core = {path = "../karkas_core", develop = true}
|
||||||
|
peewee = "^3.17.6"
|
||||||
|
pyyaml = "^6.0.1"
|
||||||
|
|
||||||
|
[package.source]
|
||||||
|
type = "directory"
|
||||||
|
url = "../karkas_blocks"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "magic-filter"
|
name = "magic-filter"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
@ -1209,27 +1262,6 @@ files = [
|
|||||||
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
{file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "karkas-blocks"
|
|
||||||
version = "0.1.0"
|
|
||||||
description = ""
|
|
||||||
optional = false
|
|
||||||
python-versions = "~3.12"
|
|
||||||
files = []
|
|
||||||
develop = true
|
|
||||||
|
|
||||||
[package.dependencies]
|
|
||||||
dash = "^2.17.1"
|
|
||||||
dash-bootstrap-components = "^1.6.0"
|
|
||||||
dash-extensions = "^1.0.18"
|
|
||||||
karkas-core = {path = "../karkas_core", develop = true}
|
|
||||||
peewee = "^3.17.6"
|
|
||||||
pyyaml = "^6.0.1"
|
|
||||||
|
|
||||||
[package.source]
|
|
||||||
type = "directory"
|
|
||||||
url = "../karkas_blocks"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "packaging"
|
name = "packaging"
|
||||||
version = "24.1"
|
version = "24.1"
|
||||||
@ -1670,6 +1702,20 @@ anyio = ">=3.4.0,<5"
|
|||||||
[package.extras]
|
[package.extras]
|
||||||
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"]
|
full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "taskgroup"
|
||||||
|
version = "0.0.0a4"
|
||||||
|
description = "backport of asyncio.TaskGroup, asyncio.Runner and asyncio.timeout"
|
||||||
|
optional = true
|
||||||
|
python-versions = "*"
|
||||||
|
files = [
|
||||||
|
{file = "taskgroup-0.0.0a4-py2.py3-none-any.whl", hash = "sha256:5c1bd0e4c06114e7a4128583ab75c987597d5378a33948a3b74c662b90f61277"},
|
||||||
|
{file = "taskgroup-0.0.0a4.tar.gz", hash = "sha256:eb08902d221e27661950f2a0320ddf3f939f579279996f81fe30779bca3a159c"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[package.dependencies]
|
||||||
|
exceptiongroup = "*"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tenacity"
|
name = "tenacity"
|
||||||
version = "9.0.0"
|
version = "9.0.0"
|
||||||
@ -1685,6 +1731,17 @@ files = [
|
|||||||
doc = ["reno", "sphinx"]
|
doc = ["reno", "sphinx"]
|
||||||
test = ["pytest", "tornado (>=4.5)", "typeguard"]
|
test = ["pytest", "tornado (>=4.5)", "typeguard"]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tomli"
|
||||||
|
version = "2.0.1"
|
||||||
|
description = "A lil' TOML parser"
|
||||||
|
optional = true
|
||||||
|
python-versions = ">=3.7"
|
||||||
|
files = [
|
||||||
|
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
|
||||||
|
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typer"
|
name = "typer"
|
||||||
version = "0.12.3"
|
version = "0.12.3"
|
||||||
@ -1763,6 +1820,7 @@ h11 = ">=0.8"
|
|||||||
httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
|
httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
|
||||||
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
||||||
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
||||||
|
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
||||||
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
||||||
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
||||||
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
|
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
|
||||||
@ -2136,5 +2194,5 @@ webhook = ["fastapi", "hypercorn"]
|
|||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "~3.12"
|
python-versions = ">=3.10,<3.13"
|
||||||
content-hash = "374abe60f0df5be4f88b1b0aeefe73b4205ff2a08625359e8191dae5795d5c8f"
|
content-hash = "e7b4aaf181c6631a67107a6287162313137c3b564222e33ef5cd1f10052bc3b8"
|
||||||
|
@ -6,7 +6,7 @@ authors = ["Максим Слипенко <maxim@slipenko.com>"]
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
|
|
||||||
[tool.poetry.dependencies]
|
[tool.poetry.dependencies]
|
||||||
python = ">=3.10,<=3.12"
|
python = ">=3.10,<3.13"
|
||||||
aiogram = "^3.10.0"
|
aiogram = "^3.10.0"
|
||||||
setuptools = "^71.0.1"
|
setuptools = "^71.0.1"
|
||||||
restrictedpython = "^7.1"
|
restrictedpython = "^7.1"
|
||||||
|
0
src/karkas_piccolo/README.md
Normal file
0
src/karkas_piccolo/README.md
Normal file
3
src/karkas_piccolo/karkas_piccolo/__main__.py
Normal file
3
src/karkas_piccolo/karkas_piccolo/__main__.py
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
from .main import main
|
||||||
|
|
||||||
|
main()
|
6
src/karkas_piccolo/karkas_piccolo/conf/apps/AppConfig.py
Normal file
6
src/karkas_piccolo/karkas_piccolo/conf/apps/AppConfig.py
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
from piccolo.conf.apps import AppConfig as OrigAppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class AppConfig(OrigAppConfig):
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
@ -0,0 +1,6 @@
|
|||||||
|
from piccolo.conf.apps import AppRegistry as OrigAppRegistry
|
||||||
|
|
||||||
|
|
||||||
|
class AppRegistry(OrigAppRegistry):
|
||||||
|
def __init__(self, apps_configs):
|
||||||
|
self.app_configs = apps_configs
|
2
src/karkas_piccolo/karkas_piccolo/conf/apps/__init__.py
Normal file
2
src/karkas_piccolo/karkas_piccolo/conf/apps/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .AppConfig import AppConfig
|
||||||
|
from .AppRegistry import AppRegistry
|
2
src/karkas_piccolo/karkas_piccolo/karkas/__init__.py
Normal file
2
src/karkas_piccolo/karkas_piccolo/karkas/__init__.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
from .get_info_path import get_info_path
|
||||||
|
from .migrate_forward import migrate_forward
|
@ -0,0 +1,9 @@
|
|||||||
|
import inspect
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def get_info_path():
|
||||||
|
caller_frame = inspect.currentframe()
|
||||||
|
caller_file = caller_frame.f_code.co_filename
|
||||||
|
caller_directory = os.path.dirname(os.path.abspath(caller_file))
|
||||||
|
return os.path.join(caller_directory, "info.json")
|
@ -0,0 +1,7 @@
|
|||||||
|
import karkas_piccolo.patches.app.finder # noqa: F401 isort:skip
|
||||||
|
|
||||||
|
from piccolo.apps.migrations.commands.forwards import run_forwards
|
||||||
|
|
||||||
|
|
||||||
|
async def migrate_forward():
|
||||||
|
await run_forwards("all")
|
8
src/karkas_piccolo/karkas_piccolo/main.py
Normal file
8
src/karkas_piccolo/karkas_piccolo/main.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import karkas_piccolo.patches.cli.finder # noqa: F401 isort:skip
|
||||||
|
import karkas_piccolo.patches.migrations # noqa: F401 isort:skip
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
from piccolo.main import main as piccolo_main
|
||||||
|
|
||||||
|
piccolo_main()
|
28
src/karkas_piccolo/karkas_piccolo/patches/app/finder.py
Normal file
28
src/karkas_piccolo/karkas_piccolo/patches/app/finder.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import typing as t
|
||||||
|
|
||||||
|
import piccolo.conf
|
||||||
|
import piccolo.conf.apps
|
||||||
|
from piccolo.conf.apps import PiccoloAppModule, PiccoloConfModule
|
||||||
|
|
||||||
|
from karkas_core.singleton import Singleton
|
||||||
|
|
||||||
|
|
||||||
|
class Finder(piccolo.conf.apps.Finder):
|
||||||
|
def get_app_modules(self):
|
||||||
|
apps = []
|
||||||
|
|
||||||
|
for k, m in self.get_app_registry().app_configs.items():
|
||||||
|
module = PiccoloAppModule(name=k)
|
||||||
|
module.APP_CONFIG = m
|
||||||
|
apps.append(module)
|
||||||
|
|
||||||
|
return apps
|
||||||
|
|
||||||
|
def get_piccolo_conf_module(
|
||||||
|
self, module_name: t.Optional[str] = None
|
||||||
|
) -> t.Optional[PiccoloConfModule]:
|
||||||
|
singleton = Singleton()
|
||||||
|
return singleton.storage["_database"]["conf"]
|
||||||
|
|
||||||
|
|
||||||
|
piccolo.conf.apps.Finder = Finder
|
97
src/karkas_piccolo/karkas_piccolo/patches/cli/finder.py
Normal file
97
src/karkas_piccolo/karkas_piccolo/patches/cli/finder.py
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
import importlib
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import typing as t
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
import piccolo.conf.apps
|
||||||
|
from piccolo.conf.apps import PiccoloAppModule, PiccoloConfModule
|
||||||
|
from piccolo.engine.sqlite import SQLiteEngine
|
||||||
|
|
||||||
|
from karkas_piccolo.conf.apps import AppRegistry
|
||||||
|
from karkas_piccolo.utils import get_info_json
|
||||||
|
|
||||||
|
|
||||||
|
class UnsafeFSLoader:
|
||||||
|
def __init__(self, path):
|
||||||
|
self.path = path
|
||||||
|
|
||||||
|
def _resolve_module_from_path(self, module_name: str):
|
||||||
|
path = Path(self.path)
|
||||||
|
|
||||||
|
if module_name != ".":
|
||||||
|
path = path.joinpath(module_name.replace(".", "/"))
|
||||||
|
|
||||||
|
if path.is_dir():
|
||||||
|
init_file_path = path / "__init__.py"
|
||||||
|
if not init_file_path.exists():
|
||||||
|
raise FileNotFoundError(f"File {init_file_path} does not exist.")
|
||||||
|
file_path = init_file_path
|
||||||
|
else:
|
||||||
|
path = path.with_suffix(".py")
|
||||||
|
if path.is_file():
|
||||||
|
file_path = path
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Module not found: {module_name}")
|
||||||
|
|
||||||
|
return file_path
|
||||||
|
|
||||||
|
def load(self):
|
||||||
|
full_path = self._resolve_module_from_path("db")
|
||||||
|
|
||||||
|
if full_path.name == "__init__.py":
|
||||||
|
module_name = full_path.parent.name
|
||||||
|
path = full_path.parent.parent.absolute()
|
||||||
|
else:
|
||||||
|
module_name = full_path.stem
|
||||||
|
path = full_path.parent.absolute()
|
||||||
|
|
||||||
|
sys.path.insert(0, str(path))
|
||||||
|
|
||||||
|
# Загружаем спецификацию модуля
|
||||||
|
spec = importlib.util.spec_from_file_location(module_name, full_path)
|
||||||
|
|
||||||
|
# Создаем модуль
|
||||||
|
module = importlib.util.module_from_spec(spec)
|
||||||
|
|
||||||
|
# Выполняем модуль
|
||||||
|
spec.loader.exec_module(module)
|
||||||
|
|
||||||
|
return module
|
||||||
|
|
||||||
|
|
||||||
|
class Finder(piccolo.conf.apps.Finder):
|
||||||
|
def get_app_modules(self):
|
||||||
|
apps = []
|
||||||
|
|
||||||
|
for k, m in self.get_app_registry().app_configs.items():
|
||||||
|
module = PiccoloAppModule(name=k)
|
||||||
|
module.APP_CONFIG = m
|
||||||
|
apps.append(module)
|
||||||
|
|
||||||
|
return apps
|
||||||
|
|
||||||
|
def get_piccolo_conf_module(
|
||||||
|
self, module_name: t.Optional[str] = None
|
||||||
|
) -> t.Optional[PiccoloConfModule]:
|
||||||
|
info = get_info_json()
|
||||||
|
|
||||||
|
fallback_module = PiccoloConfModule(
|
||||||
|
name=info["id"],
|
||||||
|
)
|
||||||
|
|
||||||
|
module_dir = os.getcwd()
|
||||||
|
|
||||||
|
print(module_dir)
|
||||||
|
|
||||||
|
module = UnsafeFSLoader(module_dir).load()
|
||||||
|
|
||||||
|
fallback_module.DB = SQLiteEngine(config={})
|
||||||
|
fallback_module.APP_REGISTRY = AppRegistry(
|
||||||
|
apps_configs={info["id"]: module.APP_CONFIG}
|
||||||
|
)
|
||||||
|
|
||||||
|
return fallback_module
|
||||||
|
|
||||||
|
|
||||||
|
piccolo.conf.apps.Finder = Finder
|
42
src/karkas_piccolo/karkas_piccolo/patches/migrations.py
Normal file
42
src/karkas_piccolo/karkas_piccolo/patches/migrations.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import typing as t
|
||||||
|
|
||||||
|
import piccolo.apps.migrations.piccolo_app
|
||||||
|
from piccolo.apps.migrations.commands.backwards import backwards
|
||||||
|
from piccolo.apps.migrations.commands.check import check
|
||||||
|
from piccolo.apps.migrations.commands.clean import clean
|
||||||
|
from piccolo.apps.migrations.commands.forwards import forwards
|
||||||
|
from piccolo.apps.migrations.commands.new import new as orig_new
|
||||||
|
from piccolo.conf.apps import AppConfig, Command
|
||||||
|
|
||||||
|
from karkas_piccolo.utils import get_info_json
|
||||||
|
|
||||||
|
|
||||||
|
async def new(
|
||||||
|
auto: bool = False,
|
||||||
|
desc: str = "",
|
||||||
|
auto_input: t.Optional[str] = None,
|
||||||
|
):
|
||||||
|
info = get_info_json()
|
||||||
|
|
||||||
|
return await orig_new(
|
||||||
|
info["id"],
|
||||||
|
auto=auto,
|
||||||
|
desc=desc,
|
||||||
|
auto_input=auto_input,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
APP_CONFIG = AppConfig(
|
||||||
|
app_name="migrations",
|
||||||
|
migrations_folder_path="",
|
||||||
|
commands=[
|
||||||
|
Command(callable=backwards, aliases=["b", "back", "backward"]),
|
||||||
|
Command(callable=check),
|
||||||
|
Command(callable=clean),
|
||||||
|
Command(callable=forwards, aliases=["f", "forward"]),
|
||||||
|
Command(callable=new, aliases=["n", "create"]),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
piccolo.apps.migrations.piccolo_app.APP_CONFIG = APP_CONFIG
|
8
src/karkas_piccolo/karkas_piccolo/utils.py
Normal file
8
src/karkas_piccolo/karkas_piccolo/utils.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
def get_info_json(path="info.json"):
|
||||||
|
with open(path, "r", encoding="utf-8") as file:
|
||||||
|
data = json.load(file)
|
||||||
|
|
||||||
|
return data
|
1131
src/karkas_piccolo/poetry.lock
generated
Normal file
1131
src/karkas_piccolo/poetry.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
2
src/karkas_piccolo/poetry.toml
Normal file
2
src/karkas_piccolo/poetry.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[virtualenvs]
|
||||||
|
in-project = true
|
19
src/karkas_piccolo/pyproject.toml
Normal file
19
src/karkas_piccolo/pyproject.toml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
[tool.poetry]
|
||||||
|
name = "karkas-piccolo"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = ""
|
||||||
|
authors = ["Maxim Slipenko <maxim@slipenko.com>"]
|
||||||
|
readme = "README.md"
|
||||||
|
|
||||||
|
[tool.poetry.scripts]
|
||||||
|
karkas-piccolo = 'karkas_piccolo.main:main'
|
||||||
|
|
||||||
|
[tool.poetry.dependencies]
|
||||||
|
python = ">=3.10,<3.13"
|
||||||
|
piccolo = { extras=["sqlite"], version = "^1.16.0" }
|
||||||
|
karkas-core = { path = "../karkas_core", develop = true }
|
||||||
|
|
||||||
|
|
||||||
|
[build-system]
|
||||||
|
requires = ["poetry-core"]
|
||||||
|
build-backend = "poetry.core.masonry.api"
|
Loading…
Reference in New Issue
Block a user