yoyogram 0.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- yoyogram-0.0.0/LICENSE +3 -0
- yoyogram-0.0.0/MANIFEST.in +1 -0
- yoyogram-0.0.0/PKG-INFO +23 -0
- yoyogram-0.0.0/pyproject.toml +3 -0
- yoyogram-0.0.0/setup.cfg +4 -0
- yoyogram-0.0.0/setup.py +31 -0
- yoyogram-0.0.0/src/_yoyo_cli/__init__.py +0 -0
- yoyogram-0.0.0/src/_yoyo_cli/cli.py +46 -0
- yoyogram-0.0.0/src/_yoyo_cli/core.py +88 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/__init__.py +0 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/__init__.py +91 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/config.py +78 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/models/__init__.py +19 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/routers/__init__.py +31 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/routers/base/__init__.py +30 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/routers/base/handlers/__init__.py +18 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/routers/base/middlewares/__init__.py +9 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/routers/base/scripts/__init__.py +6 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/routers/middlewares/__init__.py +10 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/scripts/__init__.py +20 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/utils/__init__.py +0 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/utils/menu.py +13 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/bot/utils/scheduler/__init__.py +25 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/__init__.py +0 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/main.py +7 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/__init__.py +0 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/bot.py +21 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/bots/__init__.py +41 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/data/__init__.py +0 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/data/texts.py +11 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/data/web_apps.py +2 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/project/tgbot/models/__init__.py +19 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/router/__init__.py +30 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/router/handlers/__init__.py +18 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/router/middlewares/__init__.py +9 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/router/routers/__init__.py +28 -0
- yoyogram-0.0.0/src/_yoyo_cli/templates/router/scripts/__init__.py +6 -0
- yoyogram-0.0.0/src/yoyo/__init__.py +0 -0
- yoyogram-0.0.0/src/yoyo/handlers/__init__.py +0 -0
- yoyogram-0.0.0/src/yoyo/keyboards/__init__.py +0 -0
- yoyogram-0.0.0/src/yoyo/logger.py +64 -0
- yoyogram-0.0.0/src/yoyo/middlewares/__init__.py +0 -0
- yoyogram-0.0.0/src/yoyo/models/__init__.py +0 -0
- yoyogram-0.0.0/src/yoyo/tools.py +16 -0
- yoyogram-0.0.0/src/yoyogram.egg-info/PKG-INFO +23 -0
- yoyogram-0.0.0/src/yoyogram.egg-info/SOURCES.txt +50 -0
- yoyogram-0.0.0/src/yoyogram.egg-info/dependency_links.txt +1 -0
- yoyogram-0.0.0/src/yoyogram.egg-info/entry_points.txt +2 -0
- yoyogram-0.0.0/src/yoyogram.egg-info/requires.txt +6 -0
- yoyogram-0.0.0/src/yoyogram.egg-info/top_level.txt +2 -0
- yoyogram-0.0.0/test/test.py +3 -0
yoyogram-0.0.0/LICENSE
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include yoyo_cli/templates *
|
yoyogram-0.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yoyogram
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: The framework to ease the work with huge projects with aiogram
|
|
5
|
+
Author: dhmmmhb
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Requires-Python: >=3.7
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: aiogram
|
|
12
|
+
Requires-Dist: redis
|
|
13
|
+
Requires-Dist: environs
|
|
14
|
+
Requires-Dist: aiosqlite
|
|
15
|
+
Requires-Dist: APScheduler
|
|
16
|
+
Requires-Dist: rich
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description-content-type
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-dist
|
|
22
|
+
Dynamic: requires-python
|
|
23
|
+
Dynamic: summary
|
yoyogram-0.0.0/setup.cfg
ADDED
yoyogram-0.0.0/setup.py
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="yoyogram",
|
|
5
|
+
version="0.0.0",
|
|
6
|
+
description="The framework to ease the work with huge projects with aiogram",
|
|
7
|
+
long_description=open('README.md', 'r', encoding='utf-8').read(),
|
|
8
|
+
long_description_content_type="text/markdown",
|
|
9
|
+
author="dhmmmhb",
|
|
10
|
+
package_dir={"": "src"},
|
|
11
|
+
packages=find_packages(where="src"),
|
|
12
|
+
include_package_data=True,
|
|
13
|
+
entry_points={
|
|
14
|
+
"console_scripts": [
|
|
15
|
+
"yoyo = _yoyo_cli.cli:main"
|
|
16
|
+
]
|
|
17
|
+
},
|
|
18
|
+
install_requires=[
|
|
19
|
+
"aiogram",
|
|
20
|
+
"redis",
|
|
21
|
+
"environs",
|
|
22
|
+
"aiosqlite",
|
|
23
|
+
"APScheduler",
|
|
24
|
+
"rich"
|
|
25
|
+
],
|
|
26
|
+
classifiers=[
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"License :: OSI Approved :: MIT License",
|
|
29
|
+
],
|
|
30
|
+
python_requires=">=3.7",
|
|
31
|
+
)
|
|
File without changes
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
|
|
2
|
+
import argparse
|
|
3
|
+
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
|
|
6
|
+
from _yoyo_cli.core import init_project, help_command, create_bot, establish_router
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def main():
|
|
10
|
+
# Initializing custom Console by rich module
|
|
11
|
+
console = Console()
|
|
12
|
+
|
|
13
|
+
# Creating parser and subparsers for CLI
|
|
14
|
+
parser = argparse.ArgumentParser(prog="yoyo", description="🛠 YoYoGram CLI — Generate Templates")
|
|
15
|
+
subparsers = parser.add_subparsers(dest="command")
|
|
16
|
+
|
|
17
|
+
# Help Command
|
|
18
|
+
subparsers.add_parser("help", help="Show list of available commands")
|
|
19
|
+
|
|
20
|
+
# Init Command
|
|
21
|
+
init_parser = subparsers.add_parser("init", help="Create a new project")
|
|
22
|
+
|
|
23
|
+
# Bot Command
|
|
24
|
+
bot_parser = subparsers.add_parser("bot", help="Create a new bot")
|
|
25
|
+
bot_parser.add_argument("name", help="The name of the bot")
|
|
26
|
+
|
|
27
|
+
# Router Command
|
|
28
|
+
router_parser = subparsers.add_parser("router", help="Establish a new router")
|
|
29
|
+
router_parser.add_argument("name", help="The name of the router")
|
|
30
|
+
router_parser.add_argument("index", nargs='?', help="The index of the router", default=-1)
|
|
31
|
+
router_parser.add_argument("bot_name", nargs='?', help="The name of the bot", default=None)
|
|
32
|
+
|
|
33
|
+
# Get Request
|
|
34
|
+
args = parser.parse_args()
|
|
35
|
+
|
|
36
|
+
# Handle Request
|
|
37
|
+
if args.command == "init":
|
|
38
|
+
init_project(console)
|
|
39
|
+
elif args.command == "bot":
|
|
40
|
+
create_bot(console, args.name)
|
|
41
|
+
elif args.command == "router":
|
|
42
|
+
establish_router(console, args.name, args.index, args.bot_name)
|
|
43
|
+
elif args.command == "help" or args.command is None:
|
|
44
|
+
help_command(console)
|
|
45
|
+
else:
|
|
46
|
+
help_command(console)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
|
|
2
|
+
import shutil
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import importlib.resources as pkg_resources
|
|
5
|
+
|
|
6
|
+
from rich.console import Console
|
|
7
|
+
from rich.table import Table
|
|
8
|
+
|
|
9
|
+
from _yoyo_cli import templates
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def get_project_root():
|
|
13
|
+
current = Path.cwd()
|
|
14
|
+
for parent in [current] + list(current.parents):
|
|
15
|
+
if (parent / "main.py").exists() or (parent / ".git").exists():
|
|
16
|
+
return parent
|
|
17
|
+
return current
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def init_project(console: Console):
|
|
21
|
+
dst_path = Path.cwd()
|
|
22
|
+
with pkg_resources.path(templates, "project") as template_path:
|
|
23
|
+
shutil.copytree(template_path, dst_path, dirs_exist_ok=True)
|
|
24
|
+
(dst_path / "__init__.py").unlink(missing_ok=True)
|
|
25
|
+
console.print("[green]✅ Project has been created![/green]")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def help_command(console: Console):
|
|
29
|
+
table = Table(title="🛠 Доступные команды YoYoGram CLI", style="magenta")
|
|
30
|
+
table.add_column("Command", style="cyan3", no_wrap=True)
|
|
31
|
+
table.add_column("Arguments", style="deep_sky_blue1")
|
|
32
|
+
table.add_column("Description", style="white")
|
|
33
|
+
table.add_row("init", "", "Create a new project")
|
|
34
|
+
table.add_row("bot", "bot_name", "Create a new bot")
|
|
35
|
+
table.add_row("router", "name Optional:index Optional:bot_name\nProviding bot_name it will create router by tgbot/bots/bot_name/routers/router_name path\nNot providing bot_name, it established router by the current path\nNot providing index means the last position", "Establish a new router")
|
|
36
|
+
console.print(table)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def create_bot(console: Console, bot_name: str):
|
|
40
|
+
with pkg_resources.path(templates, "bot") as template_path:
|
|
41
|
+
bots_dir = get_project_root() / "tgbot" / "bots" / bot_name
|
|
42
|
+
|
|
43
|
+
for item in template_path.rglob("*"):
|
|
44
|
+
if item.is_file():
|
|
45
|
+
rel_path = item.relative_to(template_path)
|
|
46
|
+
dst_file = bots_dir / rel_path
|
|
47
|
+
dst_file.parent.mkdir(parents=True, exist_ok=True)
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
content = item.read_text(encoding="utf-8")
|
|
51
|
+
content = content.replace("{bot_name}", bot_name)
|
|
52
|
+
dst_file.write_text(content, encoding="utf-8")
|
|
53
|
+
except UnicodeDecodeError:
|
|
54
|
+
shutil.copyfile(item, dst_file)
|
|
55
|
+
|
|
56
|
+
console.print(f"[green]✅ {bot_name} has been created by tgbot/bots/{bot_name} directory![/green]")
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def establish_router(console: Console, router_name: str, router_index: int = -1, bot_name: str = None):
|
|
60
|
+
with pkg_resources.path(templates, "router") as template_path:
|
|
61
|
+
if bot_name:
|
|
62
|
+
bots_dir = get_project_root() / "tgbot" / "bots" / bot_name / "routers" / router_name
|
|
63
|
+
else:
|
|
64
|
+
for parent in [Path.cwd()] + list(Path.cwd().parents):
|
|
65
|
+
if (parent / "routers").exists():
|
|
66
|
+
bots_dir = parent / "routers" / router_name
|
|
67
|
+
break
|
|
68
|
+
else:
|
|
69
|
+
bots_dir = get_project_root() / "tgbot" / "bots" / bot_name / "routers" / router_name
|
|
70
|
+
|
|
71
|
+
for item in template_path.rglob("*"):
|
|
72
|
+
if item.is_file():
|
|
73
|
+
rel_path = item.relative_to(template_path)
|
|
74
|
+
dst_file = bots_dir / rel_path
|
|
75
|
+
dst_file.parent.mkdir(parents=True, exist_ok=True)
|
|
76
|
+
try:
|
|
77
|
+
content = item.read_text(encoding="utf-8")
|
|
78
|
+
content = content.replace("{bot_name}", bot_name)
|
|
79
|
+
content = content.replace("{router_name}", router_name)
|
|
80
|
+
content = content.replace("{router_index}", str(router_index))
|
|
81
|
+
dst_file.write_text(content, encoding="utf-8")
|
|
82
|
+
except UnicodeDecodeError:
|
|
83
|
+
shutil.copyfile(item, dst_file)
|
|
84
|
+
|
|
85
|
+
if bot_name:
|
|
86
|
+
console.print(f"[green]✅ {router_name} has been established by tgbot/bots/{bot_name}/routers/{router_name} directory![/green]")
|
|
87
|
+
else:
|
|
88
|
+
console.print(f"[green]✅ {router_name} has been established by {str(bots_dir)} directory![/green]")
|
|
File without changes
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
|
|
3
|
+
from aiogram import Bot, Dispatcher
|
|
4
|
+
from aiogram.fsm.storage.base import DefaultKeyBuilder
|
|
5
|
+
from aiogram.fsm.storage.memory import MemoryStorage
|
|
6
|
+
from aiogram.fsm.storage.redis import RedisStorage
|
|
7
|
+
from aiogram.webhook.aiohttp_server import setup_application
|
|
8
|
+
from aiohttp import web
|
|
9
|
+
from redis import Redis
|
|
10
|
+
|
|
11
|
+
from tgbot.bots.{bot_name}.config import get_config
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def build() -> [Bot, Dispatcher]:
|
|
15
|
+
config = get_config()
|
|
16
|
+
|
|
17
|
+
bot = Bot(
|
|
18
|
+
token=config.tgbot.token
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
if config.tgbot.use_redis:
|
|
22
|
+
redis = Redis(
|
|
23
|
+
host=config.redis.host,
|
|
24
|
+
port=config.redis.port,
|
|
25
|
+
password=config.redis.password
|
|
26
|
+
)
|
|
27
|
+
key_builder = None
|
|
28
|
+
if config.redis.is_prefix:
|
|
29
|
+
key_builder = DefaultKeyBuilder(prefix=config.redis.prefix)
|
|
30
|
+
storage = RedisStorage(redis, key_builder=key_builder)
|
|
31
|
+
else:
|
|
32
|
+
storage = MemoryStorage()
|
|
33
|
+
|
|
34
|
+
dp = Dispatcher(
|
|
35
|
+
storage=storage
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
from tgbot.bots.{bot_name}.scripts import register_scripts
|
|
39
|
+
register_scripts(bot, dp)
|
|
40
|
+
from tgbot.bots.{bot_name}.utils.scheduler import register_scheduler
|
|
41
|
+
register_scheduler(bot)
|
|
42
|
+
from tgbot.bots.{bot_name}.routers import register_routers
|
|
43
|
+
register_routers(dp)
|
|
44
|
+
|
|
45
|
+
return bot, dp
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
async def start(bot: Bot, dp: Dispatcher):
|
|
49
|
+
from tgbot.bots.{bot_name}.models import connect_models
|
|
50
|
+
await connect_models()
|
|
51
|
+
|
|
52
|
+
from tgbot.bots.{bot_name}.utils.menu import register_my_commands
|
|
53
|
+
await register_my_commands(bot)
|
|
54
|
+
|
|
55
|
+
config = get_config()
|
|
56
|
+
|
|
57
|
+
if config.tgbot.use_webhook:
|
|
58
|
+
|
|
59
|
+
async def on_startup(app):
|
|
60
|
+
await bot.set_webhook(app["webhook_url"])
|
|
61
|
+
|
|
62
|
+
async def on_cleanup(app):
|
|
63
|
+
await bot.delete_webhook()
|
|
64
|
+
await dp.storage.close()
|
|
65
|
+
await bot.session.close()
|
|
66
|
+
|
|
67
|
+
app = web.Application()
|
|
68
|
+
app["bot"] = bot
|
|
69
|
+
app["dp"] = dp
|
|
70
|
+
app["webhook_url"] = config.webhook.url
|
|
71
|
+
|
|
72
|
+
setup_application(app, dp, bot=bot)
|
|
73
|
+
app.on_startup.append(on_startup)
|
|
74
|
+
app.on_cleanup.append(on_cleanup)
|
|
75
|
+
|
|
76
|
+
runner = web.AppRunner(app)
|
|
77
|
+
await runner.setup()
|
|
78
|
+
site = web.TCPSite(runner, "0.0.0.0", 8080)
|
|
79
|
+
await site.start()
|
|
80
|
+
|
|
81
|
+
try:
|
|
82
|
+
await asyncio.Event().wait()
|
|
83
|
+
finally:
|
|
84
|
+
await runner.cleanup()
|
|
85
|
+
|
|
86
|
+
else:
|
|
87
|
+
try:
|
|
88
|
+
await dp.start_polling(bot)
|
|
89
|
+
finally:
|
|
90
|
+
await dp.storage.close()
|
|
91
|
+
await bot.session.close()
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from environs import Env
|
|
3
|
+
from yoyo.logger import Logger
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@dataclass
|
|
7
|
+
class Tgbot:
|
|
8
|
+
token: str
|
|
9
|
+
admins: list[int]
|
|
10
|
+
group_id: int
|
|
11
|
+
use_redis: bool
|
|
12
|
+
use_webhook: bool
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class Redis:
|
|
17
|
+
host: str
|
|
18
|
+
port: int
|
|
19
|
+
password: str
|
|
20
|
+
is_prefix: bool
|
|
21
|
+
prefix: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass
|
|
25
|
+
class Webhook:
|
|
26
|
+
url: str
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class Payment:
|
|
31
|
+
token: str
|
|
32
|
+
currency: str
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@dataclass
|
|
36
|
+
class Misc:
|
|
37
|
+
tz: str
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@dataclass
|
|
41
|
+
class Config:
|
|
42
|
+
tgbot: Tgbot
|
|
43
|
+
redis: Redis
|
|
44
|
+
payment: Payment
|
|
45
|
+
misc: Misc
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_config() -> Config:
|
|
49
|
+
env = Env()
|
|
50
|
+
path = './tgbot/bots/{bot_name}/.env'
|
|
51
|
+
env.read_env(path)
|
|
52
|
+
|
|
53
|
+
return Config(
|
|
54
|
+
tgbot=Tgbot(
|
|
55
|
+
token=env.str("TOKEN"),
|
|
56
|
+
admins=list(map(int, env.str("ADMINS").split(' '))),
|
|
57
|
+
group_id=env.int("GROUP_ID"),
|
|
58
|
+
use_redis=env.bool("USE_REDIS"),
|
|
59
|
+
use_webhook=env.bool("USE_WEBHOOK"),
|
|
60
|
+
),
|
|
61
|
+
redis=Redis(
|
|
62
|
+
host=env.str("REDIS_HOST"),
|
|
63
|
+
port=env.int("REDIS_PORT"),
|
|
64
|
+
password=env.str("REDIS_PASSWORD"),
|
|
65
|
+
is_prefix=env.bool("REDIS_IS_PREFIX"),
|
|
66
|
+
prefix=env.str("REDIS_PREFIX"),
|
|
67
|
+
),
|
|
68
|
+
payment=Payment(
|
|
69
|
+
token=env.str("PAYMENT_PROVIDER_TOKEN"),
|
|
70
|
+
currency=env.str("PAYMENT_CURRENCY"),
|
|
71
|
+
),
|
|
72
|
+
misc=Misc(
|
|
73
|
+
tz=env.str("SCHEDULER_TZ")
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
log = Logger()
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
import yoyo
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def connect_models():
|
|
7
|
+
python_models = yoyo.tools.listdir(__file__)
|
|
8
|
+
|
|
9
|
+
for el in deepcopy(python_models):
|
|
10
|
+
if not el[-3:] == ".py":
|
|
11
|
+
python_models.remove(el)
|
|
12
|
+
python_models.remove("__init__.py")
|
|
13
|
+
python_models = list(map(lambda x: x[:-3], python_models))
|
|
14
|
+
|
|
15
|
+
package = yoyo.tools.package(__file__)
|
|
16
|
+
|
|
17
|
+
for module in python_models:
|
|
18
|
+
import_connect = importlib.import_module(f".{module}", package=package).main
|
|
19
|
+
await import_connect()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from src import yoyo
|
|
3
|
+
|
|
4
|
+
from aiogram import Dispatcher, Router
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_routers(dp: Dispatcher):
|
|
8
|
+
# Register middlewares of dispatcher (global middlewares)
|
|
9
|
+
from .middlewares import register_dp_middlewares
|
|
10
|
+
register_dp_middlewares(dp)
|
|
11
|
+
|
|
12
|
+
# Include routers to dispatcher
|
|
13
|
+
routers_list = yoyo.tools.listdir(__file__)
|
|
14
|
+
routers_list.remove("__init__.py")
|
|
15
|
+
try:
|
|
16
|
+
routers_list.remove("__pycache__")
|
|
17
|
+
except ValueError:
|
|
18
|
+
pass
|
|
19
|
+
routers_list.remove("middlewares")
|
|
20
|
+
|
|
21
|
+
routers: list[tuple[int, Router]] = []
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
package = yoyo.tools.package(__file__)
|
|
25
|
+
for module in routers_list:
|
|
26
|
+
import_get_router = importlib.import_module(f".{module}", package=package).get_router
|
|
27
|
+
router.append(import_get_router())
|
|
28
|
+
|
|
29
|
+
max_i = max(i for i, _ in routers if i != -1) + 1
|
|
30
|
+
for _, router in sorted(routers, key=lambda x: max_i if x[0] == -1 else x[0]):
|
|
31
|
+
dp.include_router(router)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import os
|
|
3
|
+
import yoyo
|
|
4
|
+
|
|
5
|
+
from aiogram import Router
|
|
6
|
+
|
|
7
|
+
from .middlewares import register_middlewares
|
|
8
|
+
from .handlers import register_handlers
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_router() -> tuple[int, Router]:
|
|
12
|
+
router = Router(name=yoyo.tools.basename(__file__))
|
|
13
|
+
|
|
14
|
+
# Register middlewares, handlers and errors
|
|
15
|
+
register_middlewares(router)
|
|
16
|
+
register_handlers(router)
|
|
17
|
+
|
|
18
|
+
# Include to router another routers
|
|
19
|
+
path = yoyo.tools.listpath(__file__)
|
|
20
|
+
path.append("routers")
|
|
21
|
+
try:
|
|
22
|
+
routers = os.listdir("\\".join(path))
|
|
23
|
+
package = yoyo.tools.package(path)
|
|
24
|
+
for module in routers:
|
|
25
|
+
import_get_router = importlib.import_module(f".{module}", package=package).get_router
|
|
26
|
+
router.include_router(import_get_router())
|
|
27
|
+
except (FileNotFoundError, TypeError):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
return 1, router
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from src import yoyo
|
|
3
|
+
|
|
4
|
+
from aiogram import Router
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_handlers(router: Router):
|
|
8
|
+
modules: list[str] = list(map(lambda x: x[:-3], yoyo.tools.listdir(__file__)))
|
|
9
|
+
modules.remove('__init__')
|
|
10
|
+
try:
|
|
11
|
+
modules.remove('__pycach')
|
|
12
|
+
except:
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
package = yoyo.tools.package(__file__)
|
|
16
|
+
for module in modules:
|
|
17
|
+
import_register = importlib.import_module(f".{module}", package=package).register
|
|
18
|
+
import_register(router)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from aiogram import Bot, Dispatcher
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Public Scripts to use it for any routers,
|
|
5
|
+
or to call it from other pieces of structure,
|
|
6
|
+
like another code (not tgbot)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
bot: Bot
|
|
10
|
+
dp: Dispatcher
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def register_scripts(work_bot: Bot, work_dp: Dispatcher):
|
|
14
|
+
global bot, dp
|
|
15
|
+
|
|
16
|
+
bot = work_bot
|
|
17
|
+
dp = work_dp
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = ['register_scripts', 'bot', 'dp']
|
|
File without changes
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from src import yoyo
|
|
3
|
+
|
|
4
|
+
from aiogram import Bot
|
|
5
|
+
from apscheduler.schedulers.asyncio import AsyncIOScheduler
|
|
6
|
+
|
|
7
|
+
from tgbot.bots.{bot_name}.data.config import get_config
|
|
8
|
+
|
|
9
|
+
scheduler: AsyncIOScheduler
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def register_scheduler(bot: Bot):
|
|
13
|
+
global scheduler
|
|
14
|
+
scheduler = AsyncIOScheduler(timezone=get_config().misc.tz)
|
|
15
|
+
|
|
16
|
+
tasks = list(map(lambda x: x[:-3], yoyo.tools.listdir(__file__)))
|
|
17
|
+
tasks.remove('__init__')
|
|
18
|
+
tasks.remove('__pycach')
|
|
19
|
+
|
|
20
|
+
package = yoyo.tools.package(__file__)
|
|
21
|
+
for module in tasks:
|
|
22
|
+
import_register = importlib.import_module(f'.{module}', package=package).register
|
|
23
|
+
import_register(scheduler, bot)
|
|
24
|
+
|
|
25
|
+
scheduler.start()
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
from asyncio import CancelledError
|
|
3
|
+
|
|
4
|
+
from aiogram import Bot, Dispatcher
|
|
5
|
+
from aiogram.fsm.storage.memory import MemoryStorage
|
|
6
|
+
from aiogram.fsm.storage.redis import RedisStorage
|
|
7
|
+
from redis import Redis
|
|
8
|
+
|
|
9
|
+
from tgbot.bots import build_bots, start_bots
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
async def build() -> list[tuple[Bot, Dispatcher]]:
|
|
13
|
+
return await build_bots()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
async def start(bots: list[tuple[Bot, Dispatcher]]):
|
|
17
|
+
await start_bots(bots)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
async def main():
|
|
21
|
+
await start(await build())
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import os
|
|
3
|
+
import yoyo
|
|
4
|
+
|
|
5
|
+
from aiogram import Bot, Dispatcher
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
async def build_bots() -> list[tuple[Bot, Dispatcher]]:
|
|
9
|
+
bots_list = yoyo.tools.listdir(__file__)
|
|
10
|
+
bots_list.remove("__init__.py")
|
|
11
|
+
try:
|
|
12
|
+
bots_list.remove("__pycache__")
|
|
13
|
+
except:
|
|
14
|
+
pass
|
|
15
|
+
|
|
16
|
+
bots: list[tuple[Bot, Dispatcher]] = []
|
|
17
|
+
|
|
18
|
+
package = yoyo.tools.package(__file__)
|
|
19
|
+
|
|
20
|
+
for module in bots_list:
|
|
21
|
+
import_build_bot = importlib.import_module(f".{module}", package=package).build_bot
|
|
22
|
+
bots.append(await import_build_bot())
|
|
23
|
+
|
|
24
|
+
return bots
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
async def start_bots(bots: list[tuple[Bot, Dispatcher]]):
|
|
28
|
+
bots_list = yoyo.tools.listdir(__file__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
bots_list.remove("__init__.py")
|
|
32
|
+
try:
|
|
33
|
+
bots_list.remove("__pycache__")
|
|
34
|
+
except:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
package = yoyo.tools.package(__file__)
|
|
38
|
+
|
|
39
|
+
for module, bot, dp in zip(bots_list, bots):
|
|
40
|
+
import_start_bot = importlib.import_module(f".{module}", package=package).start_bot
|
|
41
|
+
await import_start_bot(bot, dp)
|
|
File without changes
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from copy import deepcopy
|
|
3
|
+
import yoyo
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
async def connect_models():
|
|
7
|
+
python_models = yoyo.tools.listdir(__file__)
|
|
8
|
+
|
|
9
|
+
for el in deepcopy(python_models):
|
|
10
|
+
if not el[-3:] == ".py":
|
|
11
|
+
python_models.remove(el)
|
|
12
|
+
python_models.remove("__init__.py")
|
|
13
|
+
python_models = list(map(lambda x: x[:-3], python_models))
|
|
14
|
+
|
|
15
|
+
package = yoyo.tools.package(__file__)
|
|
16
|
+
|
|
17
|
+
for module in python_models:
|
|
18
|
+
import_connect = importlib.import_module(f".{module}", package=package).main
|
|
19
|
+
await import_connect()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import os
|
|
3
|
+
import yoyo
|
|
4
|
+
|
|
5
|
+
from aiogram import Router
|
|
6
|
+
|
|
7
|
+
from .middlewares import register_middlewares
|
|
8
|
+
from .handlers import register_handlers
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def get_router() -> tuple[int, Router]:
|
|
12
|
+
router = Router(name=yoyo.tools.basename(__file__))
|
|
13
|
+
|
|
14
|
+
# Register middlewares, handlers and errors
|
|
15
|
+
register_middlewares(router)
|
|
16
|
+
register_handlers(router)
|
|
17
|
+
|
|
18
|
+
# Include to router another routers
|
|
19
|
+
path = yoyo.tools.listpath(__file__)
|
|
20
|
+
path.append("routers")
|
|
21
|
+
try:
|
|
22
|
+
routers = os.listdir("\\".join(path))
|
|
23
|
+
package = yoyo.tools.package(path)
|
|
24
|
+
for module in routers:
|
|
25
|
+
import_get_router = importlib.import_module(f".{module}", package=package).get_router
|
|
26
|
+
router.include_router(import_get_router())
|
|
27
|
+
except (FileNotFoundError, TypeError):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
return {router_index}, router
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from src import yoyo
|
|
3
|
+
|
|
4
|
+
from aiogram import Router
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_handlers(router: Router):
|
|
8
|
+
modules: list[str] = list(map(lambda x: x[:-3], yoyo.tools.listdir(__file__)))
|
|
9
|
+
modules.remove('__init__')
|
|
10
|
+
try:
|
|
11
|
+
modules.remove('__pycach')
|
|
12
|
+
except:
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
package = yoyo.tools.package(__file__)
|
|
16
|
+
for module in modules:
|
|
17
|
+
import_register = importlib.import_module(f".{module}", package=package).register
|
|
18
|
+
import_register(router)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
from src import yoyo
|
|
3
|
+
|
|
4
|
+
from aiogram import Dispatcher, Router
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def register_routers(dp: Dispatcher):
|
|
8
|
+
# Register middlewares of dispatcher (global middlewares)
|
|
9
|
+
|
|
10
|
+
# Include routers to dispatcher
|
|
11
|
+
routers_list = yoyo.tools.listdir(__file__)
|
|
12
|
+
routers_list.remove("__init__.py")
|
|
13
|
+
try:
|
|
14
|
+
routers_list.remove("__pycache__")
|
|
15
|
+
except ValueError:
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
routers: list[tuple[int, Router]] = []
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
package = yoyo.tools.package(__file__)
|
|
22
|
+
for module in routers_list:
|
|
23
|
+
import_get_router = importlib.import_module(f".{module}", package=package).get_router
|
|
24
|
+
router.append(import_get_router())
|
|
25
|
+
|
|
26
|
+
max_i = max(i for i, _ in routers if i != -1) + 1
|
|
27
|
+
for _, router in sorted(routers, key=lambda x: max_i if x[0] == -1 else x[0]):
|
|
28
|
+
dp.include_router(router)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
import os
|
|
3
|
+
import logging
|
|
4
|
+
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class Logger(object):
|
|
9
|
+
log_file = bytes
|
|
10
|
+
EXCEPTION = 100
|
|
11
|
+
CRITICAL = 50
|
|
12
|
+
ERROR = 40
|
|
13
|
+
WARNING = 30
|
|
14
|
+
INFO = 20
|
|
15
|
+
DEBUG = 10
|
|
16
|
+
NOTSET = 0
|
|
17
|
+
|
|
18
|
+
def __init__(self):
|
|
19
|
+
today = datetime.strftime(datetime.now(), "%d-%m-%y-%H_%M_%S")
|
|
20
|
+
|
|
21
|
+
if not os.path.exists("logs"):
|
|
22
|
+
os.mkdir("logs")
|
|
23
|
+
|
|
24
|
+
LOGS_FOLDER = f"logs/log-{today}.log"
|
|
25
|
+
LOGGER_NAME = "YoYoLogger"
|
|
26
|
+
|
|
27
|
+
logging.basicConfig(
|
|
28
|
+
filename=LOGS_FOLDER,
|
|
29
|
+
filemode="w",
|
|
30
|
+
format="[%(asctime)s] [%(levelname)s] -- %(message)s",
|
|
31
|
+
datefmt="%d/%b/%y %H:%M:%S",
|
|
32
|
+
encoding="utf-8"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
self.__log = logging.getLogger(LOGGER_NAME)
|
|
37
|
+
formatter = logging.Formatter(
|
|
38
|
+
"[%(asctime)s] [%(levelname)s] -- %(message)s", datefmt="%d/%b/%y %H:%M:%S"
|
|
39
|
+
)
|
|
40
|
+
ch = logging.StreamHandler(sys.stderr)
|
|
41
|
+
ch.setFormatter(formatter)
|
|
42
|
+
|
|
43
|
+
self.__log.setLevel(self.INFO)
|
|
44
|
+
self.__methods_map = {
|
|
45
|
+
self.DEBUG: self.__log.debug,
|
|
46
|
+
self.INFO: self.__log.info,
|
|
47
|
+
self.WARNING: self.__log.warning,
|
|
48
|
+
self.ERROR: self.__log.error,
|
|
49
|
+
self.CRITICAL: self.__log.critical,
|
|
50
|
+
self.EXCEPTION: self.__log.exception,
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def __call__(self, lvl, msg, *args, **kwargs):
|
|
55
|
+
if lvl in self.__methods_map:
|
|
56
|
+
self.__methods_map[lvl](msg, *args, **kwargs)
|
|
57
|
+
else:
|
|
58
|
+
self.__log.log(lvl, msg, *args, **kwargs)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def set_level(self, level=None):
|
|
62
|
+
if level is None:
|
|
63
|
+
level = self.INFO
|
|
64
|
+
self.__log.setLevel(level)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def listdir(file: __file__):
|
|
7
|
+
return os.listdir(os.path.dirname(file))
|
|
8
|
+
|
|
9
|
+
def package(file: __file__):
|
|
10
|
+
project_root = Path(sys.modules['__main__'].file).resolve().parent
|
|
11
|
+
current_path = Path(file).resolve()
|
|
12
|
+
relative_path = current_path.relative_to(project_root)
|
|
13
|
+
return ".".join(relative_path.with_suffix('').parts)
|
|
14
|
+
|
|
15
|
+
def basename(file: __file__):
|
|
16
|
+
return file.split(os.sep)[-2]
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yoyogram
|
|
3
|
+
Version: 0.0.0
|
|
4
|
+
Summary: The framework to ease the work with huge projects with aiogram
|
|
5
|
+
Author: dhmmmhb
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
8
|
+
Requires-Python: >=3.7
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: aiogram
|
|
12
|
+
Requires-Dist: redis
|
|
13
|
+
Requires-Dist: environs
|
|
14
|
+
Requires-Dist: aiosqlite
|
|
15
|
+
Requires-Dist: APScheduler
|
|
16
|
+
Requires-Dist: rich
|
|
17
|
+
Dynamic: author
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description-content-type
|
|
20
|
+
Dynamic: license-file
|
|
21
|
+
Dynamic: requires-dist
|
|
22
|
+
Dynamic: requires-python
|
|
23
|
+
Dynamic: summary
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
MANIFEST.in
|
|
3
|
+
README
|
|
4
|
+
pyproject.toml
|
|
5
|
+
setup.py
|
|
6
|
+
src/_yoyo_cli/__init__.py
|
|
7
|
+
src/_yoyo_cli/cli.py
|
|
8
|
+
src/_yoyo_cli/core.py
|
|
9
|
+
src/_yoyo_cli/templates/__init__.py
|
|
10
|
+
src/_yoyo_cli/templates/bot/__init__.py
|
|
11
|
+
src/_yoyo_cli/templates/bot/config.py
|
|
12
|
+
src/_yoyo_cli/templates/bot/models/__init__.py
|
|
13
|
+
src/_yoyo_cli/templates/bot/routers/__init__.py
|
|
14
|
+
src/_yoyo_cli/templates/bot/routers/base/__init__.py
|
|
15
|
+
src/_yoyo_cli/templates/bot/routers/base/handlers/__init__.py
|
|
16
|
+
src/_yoyo_cli/templates/bot/routers/base/middlewares/__init__.py
|
|
17
|
+
src/_yoyo_cli/templates/bot/routers/base/scripts/__init__.py
|
|
18
|
+
src/_yoyo_cli/templates/bot/routers/middlewares/__init__.py
|
|
19
|
+
src/_yoyo_cli/templates/bot/scripts/__init__.py
|
|
20
|
+
src/_yoyo_cli/templates/bot/utils/__init__.py
|
|
21
|
+
src/_yoyo_cli/templates/bot/utils/menu.py
|
|
22
|
+
src/_yoyo_cli/templates/bot/utils/scheduler/__init__.py
|
|
23
|
+
src/_yoyo_cli/templates/project/__init__.py
|
|
24
|
+
src/_yoyo_cli/templates/project/main.py
|
|
25
|
+
src/_yoyo_cli/templates/project/tgbot/__init__.py
|
|
26
|
+
src/_yoyo_cli/templates/project/tgbot/bot.py
|
|
27
|
+
src/_yoyo_cli/templates/project/tgbot/bots/__init__.py
|
|
28
|
+
src/_yoyo_cli/templates/project/tgbot/data/__init__.py
|
|
29
|
+
src/_yoyo_cli/templates/project/tgbot/data/texts.py
|
|
30
|
+
src/_yoyo_cli/templates/project/tgbot/data/web_apps.py
|
|
31
|
+
src/_yoyo_cli/templates/project/tgbot/models/__init__.py
|
|
32
|
+
src/_yoyo_cli/templates/router/__init__.py
|
|
33
|
+
src/_yoyo_cli/templates/router/handlers/__init__.py
|
|
34
|
+
src/_yoyo_cli/templates/router/middlewares/__init__.py
|
|
35
|
+
src/_yoyo_cli/templates/router/routers/__init__.py
|
|
36
|
+
src/_yoyo_cli/templates/router/scripts/__init__.py
|
|
37
|
+
src/yoyo/__init__.py
|
|
38
|
+
src/yoyo/logger.py
|
|
39
|
+
src/yoyo/tools.py
|
|
40
|
+
src/yoyo/handlers/__init__.py
|
|
41
|
+
src/yoyo/keyboards/__init__.py
|
|
42
|
+
src/yoyo/middlewares/__init__.py
|
|
43
|
+
src/yoyo/models/__init__.py
|
|
44
|
+
src/yoyogram.egg-info/PKG-INFO
|
|
45
|
+
src/yoyogram.egg-info/SOURCES.txt
|
|
46
|
+
src/yoyogram.egg-info/dependency_links.txt
|
|
47
|
+
src/yoyogram.egg-info/entry_points.txt
|
|
48
|
+
src/yoyogram.egg-info/requires.txt
|
|
49
|
+
src/yoyogram.egg-info/top_level.txt
|
|
50
|
+
test/test.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|