Compare commits
16 Commits
948586912c
...
master
Author | SHA1 | Date | |
---|---|---|---|
a100324265 | |||
e90694f0aa | |||
13f92b2817 | |||
939bb4fef3 | |||
906770ef60 | |||
b85ca1d017 | |||
e906852abe | |||
a73534f688 | |||
d3bf927f33 | |||
2a4e3ad187 | |||
518bc0d278 | |||
eeb6d04f51 | |||
264731c755 | |||
856b389b1b | |||
1671d30444 | |||
2e60b8616d |
11
.renovaterc
11
.renovaterc
@@ -2,5 +2,16 @@
|
|||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||||
"extends": [
|
"extends": [
|
||||||
"config:base"
|
"config:base"
|
||||||
|
],
|
||||||
|
"packageRules": [
|
||||||
|
{
|
||||||
|
"matchUpdateTypes": [
|
||||||
|
"minor",
|
||||||
|
"patch",
|
||||||
|
"pin",
|
||||||
|
"digest"
|
||||||
|
],
|
||||||
|
"automerge": true
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -1,12 +1,13 @@
|
|||||||
import logging
|
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from logging import Logger
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
|
|
||||||
from modules.database_mongo import col_users
|
from modules.database_mongo import col_users
|
||||||
|
from modules.logging_utils import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger: Logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
|
@@ -3,8 +3,9 @@ from dataclasses import dataclass
|
|||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
from modules.database_sqlite import cursor
|
from modules.database_sqlite import cursor
|
||||||
|
from modules.logging_utils import get_logger
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger: logging.Logger = get_logger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -30,16 +31,12 @@ class PyroUser:
|
|||||||
### Returns:
|
### Returns:
|
||||||
* `PyroUser`: User with its database data.
|
* `PyroUser`: User with its database data.
|
||||||
"""
|
"""
|
||||||
db_entry = cursor.execute(
|
db_entry = cursor.execute("SELECT id, locale FROM users WHERE id = ?", (id,)).fetchone()
|
||||||
"SELECT id, locale FROM users WHERE id = ?", (id,)
|
|
||||||
).fetchone()
|
|
||||||
|
|
||||||
if db_entry is None:
|
if db_entry is None:
|
||||||
cursor.execute("INSERT INTO users VALUES (?, ?)", (id, locale))
|
cursor.execute("INSERT INTO users VALUES (?, ?)", (id, locale))
|
||||||
cursor.connection.commit()
|
cursor.connection.commit()
|
||||||
db_entry = cursor.execute(
|
db_entry = cursor.execute("SELECT id, locale FROM users WHERE id = ?", (id,)).fetchone()
|
||||||
"SELECT id, locale FROM users WHERE id = ?", (id,)
|
|
||||||
).fetchone()
|
|
||||||
|
|
||||||
if db_entry is None:
|
if db_entry is None:
|
||||||
raise RuntimeError("Could not find inserted user entry.")
|
raise RuntimeError("Could not find inserted user entry.")
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"start": "Start using the bot",
|
"start": "Start using the bot",
|
||||||
|
"shutdown": "Turn off the bot",
|
||||||
"language": "Change bot's language",
|
"language": "Change bot's language",
|
||||||
"remove_commands": "Unregister all commands"
|
"remove_commands": "Unregister all commands"
|
||||||
},
|
},
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"start": "Почати користуватись ботом",
|
"start": "Почати користуватись ботом",
|
||||||
|
"shutdown": "Вимкнути бота",
|
||||||
"language": "Змінити мову бота",
|
"language": "Змінити мову бота",
|
||||||
"remove_commands": "Видалити всі команди"
|
"remove_commands": "Видалити всі команди"
|
||||||
},
|
},
|
||||||
|
28
main.py
28
main.py
@@ -1,14 +1,17 @@
|
|||||||
import contextlib
|
import contextlib
|
||||||
import logging
|
import logging.config
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from os import getpid
|
from logging import Logger
|
||||||
|
from os import getpid, makedirs
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from sys import exit
|
||||||
|
|
||||||
from libbot import sync
|
from libbot.utils import json_read
|
||||||
|
|
||||||
from classes.pyroclient import PyroClient
|
from classes.pyroclient import PyroClient
|
||||||
|
from modules.logging_utils import get_logger, get_logging_config
|
||||||
|
|
||||||
# Main uses MongoDB implementation of DB
|
# Main uses MongoDB implementation of DB,
|
||||||
# but you can also select SQLite one below
|
# but you can also select SQLite one below
|
||||||
# from modules.migrator_sqlite import migrate_database
|
# from modules.migrator_sqlite import migrate_database
|
||||||
from modules.migrator_mongo import migrate_database
|
from modules.migrator_mongo import migrate_database
|
||||||
@@ -21,13 +24,11 @@ from modules.scheduler import scheduler
|
|||||||
# from convopyro import Conversation
|
# from convopyro import Conversation
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(
|
makedirs(Path("logs/"), exist_ok=True)
|
||||||
level=logging.DEBUG if sync.config_get("debug") else logging.INFO,
|
|
||||||
format="%(name)s.%(funcName)s | %(levelname)s | %(message)s",
|
|
||||||
datefmt="[%X]",
|
|
||||||
)
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logging.config.dictConfig(get_logging_config())
|
||||||
|
|
||||||
|
logger: Logger = get_logger(__name__)
|
||||||
|
|
||||||
parser = ArgumentParser(
|
parser = ArgumentParser(
|
||||||
prog="__name__",
|
prog="__name__",
|
||||||
@@ -52,15 +53,16 @@ def main():
|
|||||||
logger.info("Migration finished. Exiting...")
|
logger.info("Migration finished. Exiting...")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
client = PyroClient(
|
client = PyroClient(scheduler=scheduler, commands_source=json_read(Path("commands.json")))
|
||||||
scheduler=scheduler, commands_source=sync.json_read(Path("commands.json"))
|
|
||||||
)
|
|
||||||
# Conversation(client)
|
# Conversation(client)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
client.run()
|
client.run()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
logger.warning("Forcefully shutting down with PID %s...", getpid())
|
logger.warning("Forcefully shutting down with PID %s...", getpid())
|
||||||
|
except Exception as exc:
|
||||||
|
logger.error("An unexpected exception has occurred: %s", exc, exc_info=exc)
|
||||||
|
exit(1)
|
||||||
finally:
|
finally:
|
||||||
if client.scheduler is not None:
|
if client.scheduler is not None:
|
||||||
client.scheduler.shutdown()
|
client.scheduler.shutdown()
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
from typing import Any, Mapping
|
from typing import Any, Mapping
|
||||||
|
|
||||||
from async_pymongo import AsyncClient, AsyncCollection, AsyncDatabase
|
from async_pymongo import AsyncClient, AsyncCollection, AsyncDatabase
|
||||||
from libbot.sync import config_get
|
from libbot.utils import config_get
|
||||||
|
|
||||||
db_config: Mapping[str, Any] = config_get("database")
|
db_config: Mapping[str, Any] = config_get("database")
|
||||||
|
|
||||||
@@ -16,9 +16,7 @@ if db_config["user"] is not None and db_config["password"] is not None:
|
|||||||
db_config["name"],
|
db_config["name"],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
con_string = "mongodb://{0}:{1}/{2}".format(
|
con_string = "mongodb://{0}:{1}/{2}".format(db_config["host"], db_config["port"], db_config["name"])
|
||||||
db_config["host"], db_config["port"], db_config["name"]
|
|
||||||
)
|
|
||||||
|
|
||||||
db_client = AsyncClient(con_string)
|
db_client = AsyncClient(con_string)
|
||||||
db: AsyncDatabase = db_client.get_database(name=db_config["name"])
|
db: AsyncDatabase = db_client.get_database(name=db_config["name"])
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
import sqlite3
|
import sqlite3
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from libbot.sync import config_get
|
from libbot.utils import config_get
|
||||||
|
|
||||||
db: sqlite3.Connection = sqlite3.connect(Path(config_get("database")))
|
db: sqlite3.Connection = sqlite3.connect(Path(config_get("database")))
|
||||||
cursor: sqlite3.Cursor = db.cursor()
|
cursor: sqlite3.Cursor = db.cursor()
|
||||||
|
35
modules/logging_utils.py
Normal file
35
modules/logging_utils.py
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import logging
|
||||||
|
from logging import Logger
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Any, Dict
|
||||||
|
|
||||||
|
from libbot.utils import config_get
|
||||||
|
|
||||||
|
|
||||||
|
def get_logging_config() -> Dict[str, Any]:
|
||||||
|
return {
|
||||||
|
"version": 1,
|
||||||
|
"disable_existing_loggers": False,
|
||||||
|
"handlers": {
|
||||||
|
"file": {
|
||||||
|
"class": "logging.handlers.RotatingFileHandler",
|
||||||
|
"filename": str(Path("logs/latest.log")),
|
||||||
|
"maxBytes": 500000,
|
||||||
|
"backupCount": 10,
|
||||||
|
"formatter": "simple",
|
||||||
|
},
|
||||||
|
"console": {"class": "logging.StreamHandler", "formatter": "systemd"},
|
||||||
|
},
|
||||||
|
"formatters": {
|
||||||
|
"simple": {"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"},
|
||||||
|
"systemd": {"format": "%(name)s - %(levelname)s - %(message)s"},
|
||||||
|
},
|
||||||
|
"root": {
|
||||||
|
"level": "DEBUG" if config_get("debug") else "INFO",
|
||||||
|
"handlers": ["file", "console"],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def get_logger(name: str) -> Logger:
|
||||||
|
return logging.getLogger(name)
|
@@ -1,6 +1,6 @@
|
|||||||
from typing import Any, Mapping
|
from typing import Any, Mapping
|
||||||
|
|
||||||
from libbot.sync import config_get
|
from libbot.utils import config_get
|
||||||
from mongodb_migrations.cli import MigrationManager
|
from mongodb_migrations.cli import MigrationManager
|
||||||
from mongodb_migrations.config import Configuration
|
from mongodb_migrations.config import Configuration
|
||||||
|
|
||||||
|
@@ -2,7 +2,7 @@ from os import rename
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Mapping
|
from typing import Mapping
|
||||||
|
|
||||||
from libbot.sync import json_read
|
from libbot.utils import json_read
|
||||||
|
|
||||||
from modules.database_sqlite import cursor
|
from modules.database_sqlite import cursor
|
||||||
|
|
||||||
@@ -18,9 +18,7 @@ def migrate_database() -> None:
|
|||||||
user_locale = None if "locale" not in keys else keys["locale"]
|
user_locale = None if "locale" not in keys else keys["locale"]
|
||||||
user_card = None if "card" not in keys else keys["card"]
|
user_card = None if "card" not in keys else keys["card"]
|
||||||
|
|
||||||
cursor.execute(
|
cursor.execute("INSERT INTO users VALUES (?, ?)", (int(user), user_card, user_locale))
|
||||||
"INSERT INTO users VALUES (?, ?)", (int(user), user_card, user_locale)
|
|
||||||
)
|
|
||||||
|
|
||||||
cursor.connection.commit()
|
cursor.connection.commit()
|
||||||
rename(Path("data/database.json"), Path("data/database.migrated.json"))
|
rename(Path("data/database.json"), Path("data/database.migrated.json"))
|
||||||
|
@@ -6,6 +6,4 @@ from classes.pyroclient import PyroClient
|
|||||||
|
|
||||||
@PyroClient.on_callback_query(filters.regex("nothing")) # type: ignore
|
@PyroClient.on_callback_query(filters.regex("nothing")) # type: ignore
|
||||||
async def callback_nothing(app: PyroClient, callback: CallbackQuery):
|
async def callback_nothing(app: PyroClient, callback: CallbackQuery):
|
||||||
await callback.answer(
|
await callback.answer(text=app._("nothing", "callbacks", locale=callback.from_user.language_code))
|
||||||
text=app._("nothing", "callbacks", locale=callback.from_user.language_code)
|
|
||||||
)
|
|
||||||
|
@@ -8,6 +8,4 @@ from classes.pyroclient import PyroClient
|
|||||||
~filters.scheduled & filters.private & filters.command(["start"], prefixes=["/"]) # type: ignore
|
~filters.scheduled & filters.private & filters.command(["start"], prefixes=["/"]) # type: ignore
|
||||||
)
|
)
|
||||||
async def command_start(app: PyroClient, message: Message):
|
async def command_start(app: PyroClient, message: Message):
|
||||||
await message.reply_text(
|
await message.reply_text(app._("start", "messages", locale=message.from_user.language_code))
|
||||||
app._("start", "messages", locale=message.from_user.language_code)
|
|
||||||
)
|
|
||||||
|
@@ -18,9 +18,7 @@ async def command_language(app: PyroClient, message: Message):
|
|||||||
buttons: List[InlineButton] = []
|
buttons: List[InlineButton] = []
|
||||||
|
|
||||||
for locale, data in app.in_every_locale("metadata").items():
|
for locale, data in app.in_every_locale("metadata").items():
|
||||||
buttons.append(
|
buttons.append(InlineButton(f"{data['flag']} {data['name']}", f"language:{locale}"))
|
||||||
InlineButton(f"{data['flag']} {data['name']}", f"language:{locale}")
|
|
||||||
)
|
|
||||||
|
|
||||||
keyboard.add(*buttons)
|
keyboard.add(*buttons)
|
||||||
|
|
||||||
|
25
pyproject.toml
Normal file
25
pyproject.toml
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
[project]
|
||||||
|
name = "PyrogramBotBase"
|
||||||
|
authors = [{ name = "Profitroll" }]
|
||||||
|
readme = "README.md"
|
||||||
|
requires-python = ">=3.11"
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 108
|
||||||
|
target-version = ["py311", "py312", "py313"]
|
||||||
|
|
||||||
|
[tool.isort]
|
||||||
|
profile = "black"
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
namespace_packages = true
|
||||||
|
install_types = true
|
||||||
|
strict = true
|
||||||
|
show_error_codes = true
|
||||||
|
|
||||||
|
[tool.pylint]
|
||||||
|
disable = ["line-too-long"]
|
||||||
|
|
||||||
|
[tool.pylint.main]
|
||||||
|
extension-pkg-whitelist = ["ujson"]
|
||||||
|
py-version = 3.11
|
@@ -1,10 +1,10 @@
|
|||||||
apscheduler~=3.10.4
|
apscheduler~=3.11.0
|
||||||
|
async_pymongo==0.1.9
|
||||||
convopyro==0.5
|
convopyro==0.5
|
||||||
tgcrypto==1.2.5
|
libbot[speed,pyrogram]==4.1.0
|
||||||
uvloop==0.19.0
|
tgcrypto-pyrofork==1.2.7
|
||||||
|
uvloop==0.21.0
|
||||||
# If uses MongoDB:
|
# If uses MongoDB:
|
||||||
mongodb-migrations==1.3.1
|
mongodb-migrations==1.3.1
|
||||||
--extra-index-url https://git.end-play.xyz/api/packages/profitroll/pypi/simple
|
--extra-index-url https://git.end-play.xyz/api/packages/profitroll/pypi/simple
|
||||||
async_pymongo==0.1.4
|
|
||||||
libbot[speed,pyrogram]==3.2.0
|
|
||||||
pykeyboard==0.1.7
|
pykeyboard==0.1.7
|
Reference in New Issue
Block a user