Compare commits

..

1 Commits

  1. 7
      .gitignore
  2. 68
      README.md
  3. 16
      adminpanel/asgi.py
  4. 23
      adminpanel/config.py
  5. 126
      adminpanel/settings.py
  6. 11
      adminpanel/urls.py
  7. 15
      adminpanel/wsgi.py
  8. 40
      adminpanelapp/admin.py
  9. 5
      adminpanelapp/apps.py
  10. 142
      adminpanelapp/models.py
  11. 8
      adminpanelapp/templates/send_telegram_message.html
  12. 3
      adminpanelapp/tests.py
  13. 6
      adminpanelapp/urls.py
  14. 25
      adminpanelapp/views.py
  15. 120
      auth_docs/test_doc.html
  16. BIN
      auth_docs/test_doc.odt
  17. 22
      bot_modules/access.py
  18. 350
      bot_modules/all_orders.py
  19. 397
      bot_modules/authorize.py
  20. 4
      bot_modules/backup.py
  21. 51
      bot_modules/bd_version.py
  22. 59
      bot_modules/buttons.py
  23. 70
      bot_modules/comments.py
  24. 210
      bot_modules/groups.py
  25. 22
      bot_modules/groups_utils.py
  26. 55
      bot_modules/languages.py
  27. 84
      bot_modules/messages.py
  28. 22
      bot_modules/mod_simple_message.py
  29. 681
      bot_modules/mod_table_operate.py
  30. 70
      bot_modules/needs.py
  31. 336
      bot_modules/orders.py
  32. 138
      bot_modules/orders_cat.py
  33. 71
      bot_modules/profile.py
  34. 76
      bot_modules/projects.py
  35. 8
      bot_modules/start.py
  36. 246
      bot_modules/subscribes.py
  37. 70
      bot_modules/tasks.py
  38. 161
      bot_modules/user_in_groups.py
  39. 143
      bot_modules/user_message.py
  40. 168
      bot_modules/users.py
  41. 110
      bot_modules/users_groups_agregator.py
  42. 24
      bot_sys/aiogram_bot.py
  43. 73
      bot_sys/bd_table.py
  44. 2
      bot_sys/bot_bd.py
  45. 42
      bot_sys/bot_messages.py
  46. 76
      bot_sys/bot_subscribes.py
  47. 4
      bot_sys/config.py
  48. 8
      bot_sys/interfaces.py
  49. 1
      bot_sys/keyboard.py
  50. 2
      bot_sys/log.py
  51. 141
      bot_sys/test_bot.py
  52. 51
      bot_sys/test_log.py
  53. 4
      bot_sys/user_access.py
  54. 1
      config_auth_docs
  55. BIN
      logo.png
  56. 115
      logo.svg
  57. 118
      main.py
  58. 22
      manage.py
  59. 8
      requirements.txt
  60. 12
      template/bd_item.py
  61. 34
      template/bd_item_add.py
  62. 10
      template/bd_item_delete.py
  63. 39
      template/bd_item_edit.py
  64. 89
      template/bd_item_select.py
  65. 10
      template/bd_item_view.py
  66. 93
      template/docs_message.py
  67. 2
      template/file_message.py
  68. 4
      template/simple_message.py
  69. 4
      template/sql_request.py

7
.gitignore vendored

@ -3,10 +3,3 @@ config_root_ids
__pycache__ __pycache__
log.txt log.txt
bot.db bot.db
adminpanelapp/migrations
__init__.py
.env
tmp.py
.idea/
venv/

68
README.md

@ -1,18 +1,4 @@
# TPlatformBot ## TPlatformBot
### Видеоинструкции
Обзор проекта и кода - https://vk.com/video-210998646_456239040
Общий обзор возможностей - https://vk.com/video-210998646_456239041
Обзор возможностей пользователя - https://vk.com/video-210998646_456239042
Проекты - https://vk.com/wall-210998646_139
Работа с заказами - https://vk.com/wall-210998646_137
Админ-панель - https://vk.com/wall-210998646_126
### Модульный Telegram-бот с возможностью редактирования прав доступа, как пользователям, так и группам пользователей ### Модульный Telegram-бот с возможностью редактирования прав доступа, как пользователям, так и группам пользователей
@ -22,26 +8,23 @@
2. Резервное копирование 2. Резервное копирование
3. Профиль пользователя 3. Профиль пользователя
4. Права доступа 4. Права доступа
5. Пользователи и группы пользователей 5. Группы пользователей
6. Проекты 4. Проекты
7. Задачи 5. Задачи
8. Потребности 6. Потребности
9. Комментарии 7. Комментарии
10. Языки (сообщения и кнопки)
11. Заказы
12. Подписки
--- ---------
Данный бот позволяет создать свою площадку для взаимодействия на некоммерческой основе в мессенджере Telegram и обмениваться ресурсами и компетенциями для реализации различных проектов. Данный бот позволяет создать свою площадку для взаимодействия на некоммерческой основе в мессенджере Telegram и обмениваться ресурсами и компетенциями для реализиации различных проектов.
Сам бот разработан на языке программирования **Python** с использованием фреймворка **Aiogram**. База данных - **SQLite3**. Бам бот разработан на языке программирования **Python** с использованием фреймворка **Aiogram**. База данных - **SQLite3**.
--- ------
**Установка, первичная настройка и запуск** **Установка, первичная настройка и запуск**
> Для работы требуется, как минимум, Python 3.8. >Для работы требуется, как минимум, Python 3.8.
*** Загрузка зависимостей *** *** Загрузка зависимостей ***
@ -65,35 +48,10 @@
`config_telegram_bot_api_token` `config_telegram_bot_api_token`
Запишите в первый Telegram ID пользователей, которым будет предоставлен полный (root) доступ. Запишите в первый Telegram ID пользователей, которым будет предоставлен полный (root) доступ
Во втором файле должен быть записан api_token бота, который создаётся при помощи @BotFather. Во втором файле должен быть записан api_token бота, который создаётся при помощи @BotFather
## Тестовая версия ## Тестовая версия
Тестовая версия запущена по ссылке Тестовая версия запущена по ссылке
http://t.me/Test_TPlatform_bot http://t.me/Test_TPlatform_bot
## Запуск Админ панели
### Создайте SECRET_KEY для джанго
1. Создайте в корне проекта файл .env
2. Сгенерирйте секретный ключ. Для этого в терминале (python manage.py shell) выполните следующие команды.
from django.core.management.utils import get_random_secret_key
get_random_secret_key()
3. Вставьте полученный ключ в файл .env
PLATFORM_ADMINPANEL_SECRET_KEY='ваш секретный ключ'
4. Для отладки проекта в adminpanel/settings.py установите DEBUG = True
###
### Выполните миграции
1. python manage.py migrate
2. Создайте суперпользователя
python manage.py createsuperuser
3. Введите имя пользователя, почту и пароль
4. Запустите сервер
python manage.py runserver. Можно запустить с параметром IP:PORT, например 127.0.0.1:8080
5. Перейдите по адерсу http://127.0.0.1:8000/ (адрес выведется в терминале) и введите данные ранее созданного пользователя и пароль

16
adminpanel/asgi.py

@ -1,16 +0,0 @@
"""
ASGI config for adminpanel project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanel.settings')
application = get_asgi_application()

23
adminpanel/config.py

@ -1,23 +0,0 @@
g_telegram_bot_api_token = ''
# ---------------------------------------------------------
# Файлы для настройки, которые не коммитятся в git
telegram_bot_api_token_file_name = 'config_telegram_bot_api_token'
# ---------------------------------------------------------
# Дополнительные функции
def GetFirstLineFromFile(a_FileName):
f = open(a_FileName, 'r')
result = f.readline()
f.close()
return result
def GetAllLinesFromFile(a_FileName):
f = open(a_FileName, 'r')
result = f.readlines()
f.close()
return result
# ---------------------------------------------------------
# Основные функции
def GetTelegramBotApiToken():
global g_telegram_bot_api_token
if len(g_telegram_bot_api_token) == 0:
g_telegram_bot_api_token = str().strip(GetFirstLineFromFile(telegram_bot_api_token_file_name))
return g_telegram_bot_api_token

126
adminpanel/settings.py

@ -1,126 +0,0 @@
"""
Django settings for adminpanel project.
Generated by 'django-admin startproject' using Django 4.1.4.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
import os
from pathlib import Path
from dotenv import load_dotenv
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
load_dotenv()
SECRET_KEY = os.getenv('PLATFORM_ADMINPANEL_SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'adminpanelapp',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'adminpanel.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'adminpanel.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'bot.db'),
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = 'ru'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
ASGI_APPLICATION = 'adminpanelapp.asgi.application'
ASYNC_MODE = 'django'

11
adminpanel/urls.py

@ -1,11 +0,0 @@
from django.contrib import admin
from django.urls import path, include
from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('adminpanelapp.urls')),
path('', RedirectView.as_view(url='/admin/adminpanelapp/orders'), name='')
]

15
adminpanel/wsgi.py

@ -1,15 +0,0 @@
"""
WSGI config for adminpanel project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanel.settings')
application = get_wsgi_application()

40
adminpanelapp/admin.py

@ -1,40 +0,0 @@
from django.http import HttpResponseRedirect
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from django.utils.safestring import mark_safe
from .models import Orders
from django.contrib import admin, messages
from django.urls import reverse
class OrdersAdmin(admin.ModelAdmin):
list_display = ('orderName', 'orderCreateDateTime', 'orderDesc', 'orderAddress', 'show_photo', 'show_photopay')
actions =['send_message']
exclude = ['orderAccess', 'userID', 'orderPhoto', 'orderPhotoPay']
def show_photo(self, obj):
html = obj.get_photo_html()
return mark_safe(html)
show_photo.short_description = 'Фото'
def show_photopay(self, obj):
html = obj.get_photopay_html()
return mark_safe(html)
show_photopay.short_description = 'Чек'
def send_message(orders, request, queryset):
selected_objects = request.POST.getlist(ACTION_CHECKBOX_NAME)
if len(selected_objects) != 1:
messages.error(request, "Выберите только один объект")
return
selected_user_id = int(selected_objects[0])
obj = queryset.get(orderID=selected_user_id)
user_id = obj.userID
url = reverse('send_telegram_message', kwargs={'chat_id': user_id})
return HttpResponseRedirect(url)
send_message.short_description = 'Отправка сообщения'
admin.site.register(Orders, OrdersAdmin)

5
adminpanelapp/apps.py

@ -1,5 +0,0 @@
from django.apps import AppConfig
class AdminpanelappConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'adminpanelapp'

142
adminpanelapp/models.py

@ -1,142 +0,0 @@
import time
from urllib.parse import quote
import requests
from django.db import models
from bot_sys.config import GetTelegramBotApiToken
class Orders(models.Model):
orderID = models.AutoField(primary_key=True, verbose_name='id заказа')
userID = models.CharField(max_length=100, verbose_name='id пользователя в tg', null=True)
orderName = models.CharField(max_length=100, verbose_name='наименование', null=True)
orderDesc = models.TextField(verbose_name='описание', null=True)
orderPhoto = models.ImageField(verbose_name='фото', null=True)
orderPhotoPay = models.ImageField(verbose_name='чек')
orderAddress = models.CharField(max_length=100, verbose_name='адрес доставки', blank=True, null=True)
orderAccess = models.CharField(max_length=100, verbose_name='доступ', blank=True, null=True)
orderCreateDateTime = models.DateTimeField(auto_now_add=True, null=True, verbose_name='дата и время создания')
orderStatus = models.CharField(max_length=100, verbose_name='статус заказа', blank=True, null=True)
def get_photo_html(self, width=100, height=100, large_width=400, large_height=400):
file_id = self.orderPhoto
token = GetTelegramBotApiToken()
url = f"https://api.telegram.org/bot{token}/getFile?file_id={file_id}"
response = requests.get(url)
data = response.json()
if data['ok']:
file_path = data["result"]["file_path"]
photo_url = f"https://api.telegram.org/file/bot{token}/{quote(file_path, safe='')}"
html = f"""
<html>
<body>
<img src="{photo_url}" width="{width}" height="{height}" class="small-photo">
<img src="{photo_url}" width="{large_width}" height="{large_height}" class="large-photo">
<a href="#" onclick="togglePhoto(event)" class="button">Увеличить фото</a>
<script>
function togglePhoto(event) {{
var toggleButton = event.target;
var container = toggleButton.parentNode;
var smallPhoto = container.querySelector(".small-photo");
var largePhoto = container.querySelector(".large-photo");
if (smallPhoto.style.display === "none") {{
smallPhoto.style.display = "block";
largePhoto.style.display = "none";
toggleButton.innerHTML = "Увеличить фото";
}} else {{
smallPhoto.style.display = "none";
largePhoto.style.display = "block";
toggleButton.innerHTML = "Уменьшить фото";
}}
}}
</script>
<style>
.large-photo {{
display: none;
}}
.button {{
display: inline-block;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
text-align: center;
text-decoration: none;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
}}
</style>
</body>
</html>
"""
return html
def get_photopay_html(self, width=100, height=100, large_width=400, large_height=400):
token = GetTelegramBotApiToken()
file_id = self.orderPhotoPay
url = f"https://api.telegram.org/bot{token}/getFile?file_id={file_id}"
response = requests.get(url)
data = response.json()
if data['ok']:
file_path = data["result"]["file_path"]
photo_url = f"https://api.telegram.org/file/bot{token}/{quote(file_path, safe='')}"
html = f"""
<html>
<body>
<img src="{photo_url}" width="{width}" height="{height}" class="small-photo">
<img src="{photo_url}" width="{large_width}" height="{large_height}" class="large-photo">
<a href="#" onclick="togglePhoto(event)" class="button">Увеличить фото</a>
<script>
function togglePhoto(event) {{
var toggleButton = event.target;
var container = toggleButton.parentNode;
var smallPhoto = container.querySelector(".small-photo");
var largePhoto = container.querySelector(".large-photo");
if (smallPhoto.style.display === "none") {{
smallPhoto.style.display = "block";
largePhoto.style.display = "none";
toggleButton.innerHTML = "Увеличить фото";
}} else {{
smallPhoto.style.display = "none";
largePhoto.style.display = "block";
toggleButton.innerHTML = "Уменьшить фото";
}}
}}
</script>
<style>
.large-photo {{
display: none;
}}
.button {{
display: inline-block;
padding: 10px 20px;
background-color: #4CAF50;
color: white;
text-align: center;
text-decoration: none;
font-size: 16px;
border: none;
border-radius: 5px;
cursor: pointer;
}}
</style>
</body>
</html>
"""
return html
class Meta:
verbose_name_plural = 'Заказы'
managed = False
db_table = 'orders'

8
adminpanelapp/templates/send_telegram_message.html

@ -1,8 +0,0 @@
<form method="post">
{% csrf_token %}
<div><label for="message">Сообщение:</label></div>
<div><pre>
<textarea id="message" name="message" cols="50" rows="10" placeholder="Введите сообщение"></textarea>
</pre></div>
<div><button type="submit">Отправить сообщение</button></div>
</form>

3
adminpanelapp/tests.py

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

6
adminpanelapp/urls.py

@ -1,6 +0,0 @@
from django.urls import path, include
from .views import send_telegram_message
urlpatterns = [
path('send_telegram_message/<int:chat_id>/', send_telegram_message, name='send_telegram_message'),
]

25
adminpanelapp/views.py

@ -1,25 +0,0 @@
from django.contrib import messages
from django.http import HttpResponseRedirect
import requests
from django.urls import reverse
from django.shortcuts import render
from bot_sys.config import GetTelegramBotApiToken
def send_telegram_message(request, chat_id):
if request.method == 'POST':
message = request.POST.get('message')
bot_token = GetTelegramBotApiToken()
url = f'https://api.telegram.org/bot{bot_token}/sendMessage?text={message}&chat_id={chat_id}'
response = requests.get(url)
if response.status_code == 200:
messages.success(request, "Сообщение успешно отправлено")
back_url = reverse('')
return HttpResponseRedirect(back_url)
else:
messages.error(request, "Сообщение не отправлено")
back_url = reverse('')
return HttpResponseRedirect(back_url)
else:
return render(request, 'send_telegram_message.html')

120
auth_docs/test_doc.html

@ -1,120 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title></title>
<meta name="generator" content="LibreOffice 7.3.6.2 (Linux)"/>
<meta name="created" content="00:00:00"/>
<meta name="changed" content="2023-10-31T15:50:17.206169759"/>
<style type="text/css">
@page { size: 21cm 29.7cm; margin: 2cm }
p { line-height: 115%; margin-bottom: 0.25cm; background: transparent }
td p { orphans: 0; widows: 0; background: transparent }
a:link { color: #000080; so-language: zxx; text-decoration: underline }
a:visited { color: #800000; so-language: zxx; text-decoration: underline }
</style>
</head>
<body lang="ru-RU" link="#000080" vlink="#800000" dir="ltr"><p style="line-height: 100%; margin-bottom: 0cm">
<br/>
</p>
<p align="center" style="line-height: 100%; margin-bottom: 0cm"><font size="5" style="font-size: 18pt"><b>Регистрационные
данные</b></font></p>
<p style="line-height: 100%; margin-bottom: 0cm"><br/>
</p>
<p style="line-height: 100%; margin-bottom: 0cm"><br/>
</p>
<table width="616" cellpadding="0" cellspacing="0" style="page-break-before: auto; page-break-after: auto">
<col width="305"/>
<col width="311"/>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>ID пользователя</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_ID
</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Имя</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_NAME</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Фамилия</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_FAMILY_NAME</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Отчество</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_MIDDLE_NAME</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Дата рождения</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_BIRTHDAY</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Адрес</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_ADDRESS</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Контакты</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_CONTACTS</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Подтверждение</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.USER_CONFIRM</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Доступ</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.ACCESS</p>
</td>
</tr>
<tr valign="top">
<td width="305" style="border: none; padding: 0cm"><p align="justify">
<b>Дата создания записи</b></p>
</td>
<td width="311" style="border: none; padding: 0cm"><p align="justify">
TableFieldDestiny.CREATE_DATE</p>
</td>
</tr>
</table>
<p style="line-height: 100%; margin-bottom: 0cm"><br/>
</p>
</body>
</html>

BIN
auth_docs/test_doc.odt

Binary file not shown.

22
bot_modules/access.py

@ -13,6 +13,11 @@ from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMRequestToBDAccess(StatesGroup): class FSMRequestToBDAccess(StatesGroup):
sqlRequest = State() sqlRequest = State()
class FSMEditAccessItem(StatesGroup):
item_field = State()
class FSMEditDefaultAccessItem(StatesGroup):
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'access' module_name = 'access'
@ -87,8 +92,8 @@ moduleaccess_success_edit_message = '''✅ Доступ к модулю успе
button_names = { button_names = {
mod_simple_message.ButtonNames.START: start_button_name, mod_simple_message.ButtonNames.START: start_button_name,
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать доступ", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать доступ",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): edit_moduleaccess_access_button_name, mod_table_operate.ButtonNames.EDIT_ACCESS: edit_moduleaccess_access_button_name,
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DEFAULT_ACCESS): edit_moduleaccess_default_access_button_name, mod_table_operate.ButtonNames.EDIT_DEFAULT_ACCESS: edit_moduleaccess_default_access_button_name,
} }
messages = { messages = {
@ -97,16 +102,21 @@ messages = {
Пожалуйста, выберите действие: Пожалуйста, выберите действие:
''', ''',
mod_table_operate.Messages.SELECT_TO_EDIT: moduleaccess_select_to_edit_message, mod_table_operate.Messages.SELECT_TO_EDIT: moduleaccess_select_to_edit_message,
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): moduleaccess_edit_access_message, mod_table_operate.Messages.EDIT_ACCESS: moduleaccess_edit_access_message,
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DEFAULT_ACCESS): moduleaccess_edit_default_access_message, mod_table_operate.Messages.EDIT_DEFAULT_ACCESS: moduleaccess_edit_default_access_message,
mod_table_operate.Messages.SUCCESS_EDIT: moduleaccess_success_edit_message, mod_table_operate.Messages.SUCCESS_EDIT: moduleaccess_success_edit_message,
} }
fsm = {
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditAccessItem,
mod_table_operate.FSMs.EDIT_DEFAULT_ACCESS: FSMEditDefaultAccessItem,
}
init_access = f'{user_access.user_access_group_new}=-' init_access = f'{user_access.user_access_group_new}=-'
class ModuleAccess(mod_table_operate.TableOperateModule): class ModuleAccess(mod_table_operate.TableOperateModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, None, None, init_access, init_access, a_ChildModuleNameList, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, None, None, init_access, a_ChildModuleNameList, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
self.m_SqlRequestButtonName = self.CreateButton('sql request', sql_request_button_name) self.m_SqlRequestButtonName = self.CreateButton('sql request', sql_request_button_name)
self.m_RequestStartMessage = self.CreateMessage('equest start', request_start_message) self.m_RequestStartMessage = self.CreateMessage('equest start', request_start_message)

350
bot_modules/all_orders.py

@ -1,350 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Заказы
from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message, orders, access_utils
from bot_modules import users, user_message
from template import bd_item_select, bd_item_view, bd_item, bd_item_edit
from enum import Enum
from enum import auto
# ---------------------------------------------------------
# БД
module_name = 'all_orders'
table = orders.table
init_access = f'{user_access.user_access_group_new}=-'
# ---------------------------------------------------------
# Сообщения и кнопки
class ButtonNames(Enum):
SHOW_USER_INFO = auto()
SEND_USER_MESSAGE = auto()
ADD_TO_DESC = auto()
button_names = {}
button_names.update(orders.button_names)
button_names.pop(mod_table_operate.ButtonNames.ADD)
cur_button_names = {
mod_simple_message.ButtonNames.START: "🛒 Все заказы",
mod_table_operate.ButtonNames.SHOW: "☐ Открыть заказ",
mod_table_operate.ButtonNames.LIST: "📃 Список текущих заказов",
orders.ButtonNames.LIST_ALL: "📃 Список всех заказов",
ButtonNames.SHOW_USER_INFO: "👤 Информация о пользователе",
ButtonNames.SEND_USER_MESSAGE: "📨 Отправить сообщение пользователю",
ButtonNames.ADD_TO_DESC: "𝌴 Добавить к описанию",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать заказ",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): "☐ Загрузить чек по оплате заказа",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ADDRESS): "𝌴 Изменить адрес в заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к заказу",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.STATUS): "𝌴 Изменить статус в заказе",
mod_table_operate.EnumButton(orders.OrderStatus.NEW): "Заказ ожидает модерации",
mod_table_operate.EnumButton(orders.OrderStatus.PAY): "Заказ ожидает оплаты",
mod_table_operate.EnumButton(orders.OrderStatus.ADDRESS): "Заказ ожидает уточнения адреса",
mod_table_operate.EnumButton(orders.OrderStatus.FINISH): "Заказ выполнен",
mod_table_operate.ButtonNames.DEL: "❌ Удалить заказ",}
button_names.update(cur_button_names)
messages = {}
messages.update(orders.messages)
cur_messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.STATUS): f'''
Текущий статус заказа:
#{orders.status_field}
Введите новый статус заказа:
''',
mod_table_operate.Messages.OPEN: f'''
<b>Номер заказа: #{orders.key_name} </b>
<b>Заказ: #{orders.name_field}</b>
<b>Описание и состав заказа:</b> #{orders.desc_field}
<b>Статус:</b> #{orders.status_field}
<b>Пользователь:</b> #{orders.user_id_field}
<b>Адрес доставки:</b> #{orders.address_field}
<b>Время создания:</b> #{orders.create_datetime_field}
''',
mod_table_operate.InlineMessage(ButtonNames.ADD_TO_DESC): f'''
Текущее описание заказа:
<code>#{orders.desc_field}</code>
Введите дополение к описанию заказа:
''',
}
messages_notification = {
mod_table_operate.NotificationMessage(orders.OrderStatus.NEW): f'''Статус заказа "#{orders.name_field}" изменён на - ожидает модерации''',
mod_table_operate.NotificationMessage(orders.OrderStatus.PAY): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ ожидает оплаты.
<b>Описание заказа:</b>
#{orders.desc_field}
Оплатите заказ и прикрепите чек об оплате к заказу. Для этого проследуйте по пути "Главное меню"->"Заказы"->"Загрузить чек по оплате моего заказа"
Или воспользуйтесь кнопкой:''',
mod_table_operate.NotificationMessage(orders.OrderStatus.ADDRESS): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ ожидает указания адреса доставки.
<b>Описание заказа:</b>
#{orders.desc_field}
Для этого проследуйте по пути "Главное меню"->"Заказы"->"Редактировать мой заказ"->"Изменить адрес в моём заказе"''',
mod_table_operate.NotificationMessage(orders.OrderStatus.FINISH): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ выполнен''',
}
messages.update(orders.messages_order_status)
messages.update(messages_notification)
messages.update(cur_messages)
def GetCurItemsTemplate(a_Bot, a_TableName, a_StatusFieldName, a_ParentIDFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID):
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_StatusFieldName} != ?'
return a_Bot.SQLRequest(request, param = ([a_ParentID, str(orders.OrderStatus.FINISH)]))
return GetBDItems
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_ParentIDFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID):
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ?'
return a_Bot.SQLRequest(request, param = ([a_ParentID]))
return GetBDItems
class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
def __init__(self, a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName, a_OnlyCurrent = False):
super().__init__(a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName)
self.m_OnlyCurrent = a_OnlyCurrent
def GetItemsFunc(self):
if self.m_OnlyCurrent:
return GetCurItemsTemplate(self.m_Bot, self.m_TableName, orders.status_field, self.m_ParentIDFieldName)
return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName)
class ModuleAllOrders(orders.ModuleOrders):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetInitBDCommands(self):
# уже сделано в ModuleUserOrders
return [
access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_DefInitAccess),
]
def GetName(self):
return module_name
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName, a_OnlyCurrent = True)
def SelectSourceForAllTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName)
def GetButtonNameAndKeyValueAndAccess(self, a_Item):
user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID)
n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item)
return n + "," + str(a_Item[user_field_id]), k, a
def GetPayInlineKeyboardFunc(self, a_ItemID, a_Destiny):
def PayInlineKeyboard(a_Message, a_UserGroups):
#print('PayInlineKeyboard', a_Message, a_UserGroups, a_ItemID)
cur_buttons = []
orders_mod = self.GetModule(orders.module_name)
dst = a_Destiny
if orders_mod:
prefix = orders_mod.m_EditPrefix.get(dst, None)
if prefix:
access = orders_mod.GetAccessForEditKeyboardButtons(orders_mod.m_Table.GetFieldByDestiny(dst))
cur_buttons += [
keyboard.InlineButtonWithAccess(orders_mod.GetButton(mod_table_operate.EditButton(dst)), prefix, a_ItemID, orders_mod.GetAccess(), access),
]
#print('cur_buttons', cur_buttons, a_Message, a_UserGroups, a_ItemID)
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups)
return PayInlineKeyboard
async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID):
await super().OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID)
if a_Field.m_Destiny == bd_table.TableFieldDestiny.STATUS:
key_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
item = bd_item.GetBDItemsTemplate(self.m_Bot, self.m_Table.GetName(), key_field)(a_ItemID)
if len(item) < 1:
self.m_Log.Error(f'Не удалось оповестить по заказу №{a_ItemID}.')
return
item = item[0]
user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID)
parent_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
status_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.STATUS)
#print('OnChangeField', item, user_field_id, status_field_id)
owner_id = item[user_field_id]
new_status = item[status_field_id]
parent_id = item[parent_field_id]
msg = self.GetMessage(mod_table_operate.NotificationMessage(new_status))
parent_id_msg = None
if msg:
name = self.GetMessageNameWithTableFieldDestinyAndValue(mod_table_operate.NotificationMessage(new_status), bd_table.TableFieldDestiny.PARENT_ID, parent_id)
#print('name', name, msg.GetLanguage())
parent_id_msg = msg.FindMessageForLang(name, msg.GetLanguage())
if parent_id_msg:
msg = parent_id_msg
if not msg:
self.m_Log.Error(f'Не удалось оповестить по заказу №{a_ItemID}. Пустое сообщение для нового статуса {new_status}')
return
msg = self.UpdateMessage(msg, None, item)
inline_keyboard = None
#print('new_status', str(orders.OrderStatus.PAY), new_status)
if new_status == str(orders.OrderStatus.PAY):
inline_keyboard = self.GetPayInlineKeyboardFunc(a_ItemID, bd_table.TableFieldDestiny.PHOTO_PAY)
elif new_status == str(orders.OrderStatus.ADDRESS):
inline_keyboard = self.GetPayInlineKeyboardFunc(a_ItemID, bd_table.TableFieldDestiny.ADDRESS)
await self.SendMessageToUser(msg, owner_id, a_GetInlineButtonsFunc = inline_keyboard)
def GetStartButtons(self, a_Message, a_UserGroups):
return [
[mod_table_operate.ButtonNames.LIST, user_access.AccessMode.VIEW],
[mod_table_operate.ButtonNames.EDIT, user_access.AccessMode.EDIT],
[mod_table_operate.ButtonNames.ADD, user_access.AccessMode.ADD],
[mod_table_operate.ButtonNames.DEL, user_access.AccessMode.DELETE],
]
def GetViewItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID):
table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName()
cur_item = mod_table_operate.GetCurItem(self.m_Bot, table_name, key_name, a_ItemID)
user_id = None
user_id_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID)
key_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)
if user_id_field_index and cur_item and cur_item[user_id_field_index]:
user_id = cur_item[user_id_field_index]
if not user_id:
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, [], a_UserGroups)
cur_buttons = []
for dst in bd_table.TableFieldDestiny.DESC, bd_table.TableFieldDestiny.STATUS:
access = self.GetAccessForEditKeyboardButtons(self.m_Table.GetFieldByDestiny(dst))
btn = mod_table_operate.EditButton(dst)
prefix = self.m_EditPrefix.get(dst, None)
if prefix:
cur_buttons += [
keyboard.InlineButtonWithAccess(self.GetButton(btn), prefix, cur_item[key_field_index], self.GetAccess(), access),
]
access = self.GetAccessForEditKeyboardButtons(self.m_Table.GetFieldByDestiny(bd_table.TableFieldDestiny.DESC))
a_Button = ButtonNames.ADD_TO_DESC
prefix = self.m_EditPrefix.get(a_Button, None)
cur_buttons += [
keyboard.InlineButtonWithAccess(self.GetButton(a_Button), prefix, cur_item[key_field_index], self.GetAccess(), access),
]
user_message_mod = self.GetModule(user_message.module_name)
if user_message_mod:
cur_buttons += [
keyboard.InlineButtonWithAccess(self.GetButton(ButtonNames.SEND_USER_MESSAGE), user_message_mod.GetAddPrefix(), user_id, user_message_mod.GetAccess(), user_access.AccessMode.ADD),
]
users_mod = self.GetModule(users.module_name)
if users_mod:
cur_buttons += [
keyboard.InlineButtonWithAccess(self.GetButton(ButtonNames.SHOW_USER_INFO), users_mod.GetShowPrefix(), user_id, users_mod.GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups)
def RegisterAddToDesc(self):
a_AccessMode = user_access.AccessMode.EDIT
a_Button = ButtonNames.ADD_TO_DESC
a_ButtonName = self.GetButton(a_Button)
a_EditMessage = self.GetMessage(mod_table_operate.InlineMessage(a_Button))
a_Field = self.m_Table.GetFieldByDestiny(bd_table.TableFieldDestiny.DESC)
a_FieldName = a_Field.m_Name
a_FieldType = bd_item.FieldType.text
if a_Field.m_Type == bd_table.TableFieldType.PHOTO:
a_FieldType = bd_item.FieldType.photo
if not a_ButtonName or not a_EditMessage:
return
async def OnChange(a_ItemID, a_ItemData, a_EditUserID):
await self.OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID)
return self.OnChange()
table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName()
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc
GetAccess = self.m_GetAccessFunc
async def EditBDItemFunc(a_ItemData, a_UserID):
a_KeyName = key_name
a_TableName = table_name
item_id = a_ItemData[a_KeyName]
field_value = a_ItemData[a_FieldName]
cur_item = mod_table_operate.GetCurItem(self.m_Bot, table_name, key_name, item_id)
desc = ""
desc_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.DESC)
if desc_field_index and cur_item and cur_item[desc_field_index]:
desc = cur_item[desc_field_index]
new_value = desc + "\n" + field_value
res, error = bd_item.EditBDItemInTableTemplate(self.m_Bot, a_TableName, a_KeyName, a_FieldName)(item_id, new_value)
if error:
self.m_Bot.GetLog().Error(f'Пользователю {a_UserID} не удалось изменить поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}. Ошибка: {error}')
else:
self.m_Bot.GetLog().Success(f'Пользователь {a_UserID} добавил в поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={new_value}. Старое {desc}.')
await OnChange(item_id, a_ItemData, a_UserID)
return res, error
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True)
a_Prefix = bd_item_edit.CustomEditBDItemRegisterHandlers(self.m_Bot, \
EditBDItemFunc,
self.SelectSourceTemplate(a_Prefix, a_ButtonName), \
mod_table_operate.MakeFSMForAddAndEdit(self.GetName(), a_FieldName), \
self.GetMessage(mod_table_operate.Messages.SELECT_TO_EDIT), \
self.ShowMessageTemplate(a_EditMessage), \
self.ShowMessageTemplate(self.GetMessage(mod_table_operate.Messages.SUCCESS_EDIT)), \
table_name, \
key_name, \
a_FieldName, \
self.PostProccessingForFieldForEditTemplate(a_Field),\
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
self.AdditionalKeyboardForEditTemplate(a_Field),\
edit_keyboard_func, \
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
self.m_EditPrefix.update({a_Button: a_Prefix})
def RegisterHandlers(self):
super().RegisterHandlers()
self.RegisterAddToDesc()

397
bot_modules/authorize.py

@ -1,397 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Авторизация или регистрация в кооперативе или другой организации
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes, config
from bot_modules import mod_table_operate, mod_simple_message, users_groups_agregator, groups_utils
from template import docs_message, bd_item, bd_item_select
from enum import Enum
from enum import auto
# ---------------------------------------------------------
# БД
module_name = 'authorize'
table_name = module_name
user_id_field = 'userID'
user_name_field = 'userName'
user_family_name_field = 'userFamilyName'
user_middle_name_field = 'userMiddleName'
user_birthday_field = 'userBirthday'
user_address_field = 'userAddress'
user_contacts_field = 'userContacts'
user_confirm_field = 'userConfirm'
user_auth_docs_field = 'authDocs'
user_photo_pay_field = 'photoPay'
access_field = 'authorizeAccess'
create_datetime_field = 'authorizeCreateDateTime'
user_id_table_field = bd_table.TableField(user_id_field, bd_table.TableFieldDestiny.USER_ID, bd_table.TableFieldType.INT)
class ConfirmStatus(Enum):
YES = auto()
NO = auto()
table = bd_table.Table(table_name, [
user_id_table_field,
bd_table.TableField(user_name_field, bd_table.TableFieldDestiny.USER_NAME, bd_table.TableFieldType.STR),
bd_table.TableField(user_family_name_field, bd_table.TableFieldDestiny.USER_FAMILY_NAME, bd_table.TableFieldType.STR),
bd_table.TableField(user_middle_name_field, bd_table.TableFieldDestiny.USER_MIDDLE_NAME, bd_table.TableFieldType.STR),
bd_table.TableField(user_birthday_field, bd_table.TableFieldDestiny.USER_BIRTHDAY, bd_table.TableFieldType.STR),
bd_table.TableField(user_address_field, bd_table.TableFieldDestiny.USER_ADDRESS, bd_table.TableFieldType.STR),
bd_table.TableField(user_contacts_field, bd_table.TableFieldDestiny.USER_CONTACTS, bd_table.TableFieldType.STR),
bd_table.TableField(user_confirm_field, bd_table.TableFieldDestiny.USER_CONFIRM, bd_table.TableFieldType.ENUM, a_Enum = ConfirmStatus),
bd_table.TableField(user_auth_docs_field, bd_table.TableFieldDestiny.AUTH_PHOTO_DOCS, bd_table.TableFieldType.PHOTO),
bd_table.TableField(user_photo_pay_field, bd_table.TableFieldDestiny.PHOTO_PAY, bd_table.TableFieldType.PHOTO),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
]
,
[
[user_id_table_field],
]
)
init_access = f'{user_access.user_access_group_new}=vea'
def_init_access = f'{user_access.user_access_group_new}=a'
def GetAuthorizeItem(a_Bot, a_UserID):
items = bd_item.GetBDItemsTemplate(a_Bot, table_name, user_id_field)(a_UserID)
if len(items) == 1:
return items[0]
return None
# ---------------------------------------------------------
# Сообщения и кнопки
class ButtonNames(Enum):
LIST_AUTH_DOCS = auto()
button_names = {
mod_simple_message.ButtonNames.START: "🔑 Авторизация",
mod_table_operate.ButtonNames.LIST: "≣ Список авторизаций пользователей",
mod_table_operate.ButtonNames.ADD: "📨 Заявка на вступление",
ButtonNames.LIST_AUTH_DOCS: "📨 Регистрационные документы",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать свои данные",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_ID): "☐ Изменить id пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_NAME): "☐ Изменить имя пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_FAMILY_NAME): "☐ Изменить фамилию пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_MIDDLE_NAME): "☐ Изменить отчество пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_BIRTHDAY): "☐ Изменить дату рождения пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_ADDRESS): "☐ Изменить адрес пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_CONTACTS): "☐ Изменить контакты пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_CONFIRM): "☐ Изменить подтверждение пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.USER_ID): "☐ Изменить id пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Доступ к авторизации пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.AUTH_PHOTO_DOCS): "☐ Загрузить подписанные документы",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): "☐ Оплатить членский взнос",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Доступ к авторизации пользователя",
mod_table_operate.ButtonNames.DEL: "❌ Удалить авторизацию пользователя",
mod_table_operate.EnumButton(ConfirmStatus.YES): "Да, все данные верны",
mod_table_operate.EnumButton(ConfirmStatus.NO): "Нет, данные не верны",
}
class Messages(Enum):
LIST_AUTH_DOCS = auto()
LIST_AUTH_DOCS_ERROR = auto()
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
Messages.LIST_AUTH_DOCS: '''
ваши регистрационные документы:
''',
Messages.LIST_AUTH_DOCS_ERROR: '''
Ошибка получения документов. Обратитесь в техподдержку.
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите пользователя:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, пользователь не найден
''',
mod_table_operate.Messages.OPEN: f'''
<b>Пользователь: #{user_id_field}</b>
Имя: #{user_name_field}
Фамилия: #{user_family_name_field}
Отчество: #{user_middle_name_field}
Дата рождения: #{user_birthday_field}
Адрес: #{user_address_field}
Контакты: #{user_contacts_field}
Подтверждение авторизации: #{user_confirm_field}
Время создания: #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_NAME): '''
Авторизация. Шаг 1
Введите своё имя:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_FAMILY_NAME): '''
Авторизация. Шаг 2
Введите свою фамилию:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_MIDDLE_NAME): '''
Авторизация. Шаг 3
Введите своё отчество:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_BIRTHDAY): '''
Авторизация. Шаг 4
Введите свою дату рождения в формате ДД.ММ.ГГГГ:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_ADDRESS): '''
Авторизация. Шаг 5
Введите свой домашний адрес:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_CONTACTS): '''
Авторизация. Шаг 6
Введите свои контакты:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.USER_CONFIRM): f'''
Авторизация. Шаг 7
Имя: #{user_name_field}
Фамилия: #{user_family_name_field}
Отчество: #{user_middle_name_field}
Дата рождения: #{user_birthday_field}
Адрес: #{user_address_field}
Контакты: #{user_contacts_field}
Подтверждение авторизации: #{user_confirm_field}
Подтвердите свои данные:
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Вы успешно зарегистрированы! Посмотрите документы и отправьте фотографии подписанных документов''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите пользователя, у которого вы хотите отредактировать данные.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_NAME): f'''
Текущее имя пользователя:
#{user_name_field}
Введите новое имя пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_FAMILY_NAME): f'''
Текущая фамилия пользователя:
#{user_family_name_field}
Введите новую фамилию пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_MIDDLE_NAME): f'''
Текущее отчество пользователя:
#{user_middle_name_field}
Введите новое отчество пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_BIRTHDAY): f'''
Текущая дата рождения пользователя:
#{user_birthday_field}
Введите новую дату рождения пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_ADDRESS): f'''
Текущий адрес пользователя:
#{user_address_field}
Введите новый адрес пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_CONTACTS): f'''
Текущие контакты пользователя:
#{user_contacts_field}
Введите новые контакты пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.USER_CONFIRM): f'''
Текущее подтвержение пользователя:
#{user_confirm_field}
Введите новое подтверждение пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.AUTH_PHOTO_DOCS): f'''
Загрузите подписанный документ:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO_PAY): f'''
Загрузите чек по оплате ЧВ:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к проекту:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Данные успешно отредактированы!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите пользователя, у которого вы хотите удалить авторизованные данные.
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Данные пользователя успешно удалены!''',
}
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Данные по авторизации созданы''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Данные по авторизации отредактированы''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Данные по авторизации удалены''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Данные по авторизации отредактированы #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Данные по авторизации удалены #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Данные по авторизации созданы''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Данные по авторизации отредактированы''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Данные по авторизации удалены''',
}
messages.update(messages_subscribes)
messages_confirm_status = {
mod_table_operate.EnumMessageForView(ConfirmStatus.YES): f'''Да, все данные верны''',
mod_table_operate.EnumMessageForView(ConfirmStatus.NO): f'''Нет, данные не верны''',
}
messages.update(messages_confirm_status)
class ModuleAuthorize(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, def_init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name
def GetAccessForEditKeyboardButtons(self, a_Field):
cur_dict = {
bd_table.TableFieldDestiny.USER_ID: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_NAME: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_FAMILY_NAME: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_MIDDLE_NAME: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_BIRTHDAY: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_ADDRESS: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_CONTACTS: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.USER_CONFIRM: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.ACCESS: user_access.AccessMode.NONE,
bd_table.TableFieldDestiny.AUTH_PHOTO_DOCS: user_access.AccessMode.ADD,
bd_table.TableFieldDestiny.PHOTO_PAY: user_access.AccessMode.ADD,
}
return cur_dict.get(a_Field.m_Destiny, super().GetAccessForEditKeyboardButtons(a_Field))
def GetButtonNameAndKeyValueAndAccess(self, a_Item):
key_name_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID)
name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_NAME)
fam_name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_FAMILY_NAME)
access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)
assert key_name_id != None
assert name_field_id != None
assert fam_name_field_id != None
assert access_field_id != None
return \
a_Item[name_field_id] + ' ' + a_Item[fam_name_field_id] + '(' + str(a_Item[key_name_id]) +')',\
a_Item[key_name_id],\
a_Item[access_field_id]
async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID):
super().OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID)
user_id_field_name = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.USER_ID)
user_id = a_ItemData[user_id_field_name]
user_confirm_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_CONFIRM)
auth_docs_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.AUTH_PHOTO_DOCS)
pay_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PHOTO_PAY)
item = GetAuthorizeItem(self.m_Bot, user_id)
if item and item[user_confirm_field_id] != '' and item[auth_docs_field_id] != '' and item[pay_field_id] != '':
users_groups_agregator.AddUserInGroup(self.m_Bot, user_id, user_access.user_access_group_auth_users)
def GetStartButtons(self, a_Message, a_UserGroups):
user_id = str(a_Message.from_user.id)
item = GetAuthorizeItem(self.m_Bot, user_id)
user_confirm_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_CONFIRM)
cur_buttons = []
if item and item[user_confirm_field_id] == self.GetMessage(mod_table_operate.EnumMessageForView(ConfirmStatus.YES)).GetDesc():
cur_buttons += [[ButtonNames.LIST_AUTH_DOCS, user_access.AccessMode.VIEW]]
cur_buttons += [[mod_table_operate.EditButton(bd_table.TableFieldDestiny.AUTH_PHOTO_DOCS), user_access.AccessMode.VIEW]]
cur_buttons += [[mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY), user_access.AccessMode.VIEW]]
else:
cur_buttons += [[mod_table_operate.ButtonNames.ADD, user_access.AccessMode.ADD]]
return cur_buttons + [
[mod_table_operate.ButtonNames.LIST, user_access.AccessMode.VIEW],
[mod_table_operate.ButtonNames.DEL, user_access.AccessMode.DELETE],
[mod_table_operate.ButtonNames.EDIT, user_access.AccessMode.EDIT],
]
def RegisterHandlers(self):
super().RegisterHandlers()
def GetFilesFunc(a_user_id):
files = GetAuthDocs()
cur_dict = GetReplaceDictFunc(self.m_Bot, a_user_id)
result = {}
for f in files:
result.update({f: cur_dict})
return result
button_name = self.GetButton(ButtonNames.LIST_AUTH_DOCS)
if button_name:
self.m_Bot.RegisterMessageHandler(
docs_message.DocFilesTemplate(
self.m_Bot,
GetFilesFunc,
self.GetMessage(Messages.LIST_AUTH_DOCS),
self.m_GetAccessFunc,
self.m_GetStartKeyboardButtonsFunc,
None,
self.GetMessage(Messages.LIST_AUTH_DOCS_ERROR),
access_mode = user_access.AccessMode.VIEW
),
bd_item.GetCheckForTextFunc(button_name)
)
def AddBDItemFunc(self, a_ItemData, a_UserID):
a_ItemData[user_id_field] = a_UserID
a_ItemData[user_auth_docs_field] = ''
a_ItemData[user_photo_pay_field] = ''
result = super().AddBDItemFunc(a_ItemData, a_UserID)
return result
def GetKeyFieldDestiny(self):
return bd_table.TableFieldDestiny.USER_ID
def GetInitBDCommands(self):
return super(). GetInitBDCommands() + [
groups_utils.CreateGroupRequest(user_access.user_access_group_auth_users)
]
def GetReplaceDictFunc(a_Bot, a_user_id):
item = GetAuthorizeItem(a_Bot, a_user_id)
if not item:
return None
result = {}
i = 0
for f in table.GetFields():
result.update({str(f.m_Destiny): str(item[i])})
i += 1
print(result)
return result
auth_docs_file_name = 'config_auth_docs'
g_auth_docs = []
def GetAuthDocs():
global g_auth_docs
if len(g_auth_docs) == 0:
root_ids = config.GetAllLinesFromFile(auth_docs_file_name)
for i in root_ids:
g_auth_docs += [config.ClearReadLine(i)]
return g_auth_docs

4
bot_modules/backup.py

@ -47,8 +47,8 @@ messages = {
init_access = f'{user_access.user_access_group_new}=-' init_access = f'{user_access.user_access_group_new}=-'
class ModuleBackup(mod_simple_message.SimpleMessageModule): class ModuleBackup(mod_simple_message.SimpleMessageModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(messages, button_names, init_access, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
self.m_BackupBDButtonName = self.CreateButton('backup bd', backup_bd_button_name) self.m_BackupBDButtonName = self.CreateButton('backup bd', backup_bd_button_name)
self.m_BackupBDMessage = self.CreateMessage('backup bd', backup_bd_message) self.m_BackupBDMessage = self.CreateMessage('backup bd', backup_bd_message)

51
bot_modules/bd_version.py

@ -1,51 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Версия БД
# Этот модуль нужен для того, чтобы проводить миграции на новую версию. Он записывает в БД номер текущей версии.
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes
from bot_modules import mod_table_operate, mod_simple_message
# ---------------------------------------------------------
# БД
module_name = 'bd_version'
table_name = module_name
base_version_number_field = 'baseVersionNumber'
sub_version_number_field = 'subVersionNumber'
table_base_version_number_field = bd_table.TableField(base_version_number_field, bd_table.TableFieldDestiny.VERSION_NUMBER, bd_table.TableFieldType.INT)
table_sub_version_number_field = bd_table.TableField(sub_version_number_field, bd_table.TableFieldDestiny.SUB_VERSION_NUMBER, bd_table.TableFieldType.INT)
table = bd_table.Table(table_name, [
table_base_version_number_field,
table_sub_version_number_field,
],
[
[table_base_version_number_field, table_sub_version_number_field],
])
init_access = f'{user_access.user_access_group_new}=-'
# ---------------------------------------------------------
# Сообщения и кнопки
button_names = {
}
messages = {
}
class ModuleBDVersion(mod_table_operate.TableOperateModule):
def __init__(self, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, None, None, init_access, init_access, None, None, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name
def GetInitBDCommands(self):
return super(). GetInitBDCommands() + [
f"INSERT OR IGNORE INTO {table_name} ({base_version_number_field}, {sub_version_number_field}) VALUES ('{1}', '{1}');"
]

59
bot_modules/buttons.py

@ -7,6 +7,29 @@ from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_messages
from bot_modules import mod_table_operate, mod_simple_message, access_utils from bot_modules import mod_table_operate, mod_simple_message, access_utils
from template import bd_item from template import bd_item
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateButton(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditButtonPhotoItem(StatesGroup):
item_id = State()
item_field = State()
class FSMEditButtonNameItem(StatesGroup):
item_id = State()
item_field = State()
class FSMEditButtonDescItem(StatesGroup):
item_id = State()
item_field = State()
class FSMEditButtonAccessItem(StatesGroup):
item_id = State()
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'buttons' module_name = 'buttons'
@ -27,7 +50,7 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
table_name_field, table_name_field,
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
table_parent_id_field, table_parent_id_field,
@ -39,6 +62,14 @@ table = bd_table.Table(table_name, [
init_access = f'{user_access.user_access_group_all}=-' init_access = f'{user_access.user_access_group_all}=-'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateButton,
mod_table_operate.FSMs.EDIT_NAME: FSMEditButtonNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditButtonDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditButtonPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditButtonAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -47,10 +78,10 @@ button_names = {
mod_table_operate.ButtonNames.LIST: "📃 Список названий кнопок", mod_table_operate.ButtonNames.LIST: "📃 Список названий кнопок",
mod_table_operate.ButtonNames.ADD: "☑ Добавить название кнопки", mod_table_operate.ButtonNames.ADD: "☑ Добавить название кнопки",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать названия кнопок", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать названия кнопок",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение у названия кнопок", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у названия кнопок",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название у названия кнопок", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у названия кнопок",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание у названия кнопок", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание у названия кнопок",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к названию кнопки", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к названию кнопки",
mod_table_operate.ButtonNames.DEL: "❌ Удалить название кнопки", mod_table_operate.ButtonNames.DEL: "❌ Удалить название кнопки",
} }
@ -72,17 +103,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' mod_table_operate.Messages.CREATE_NAME: '''
Создание названия кнопки Шаг 1 Создание названия кнопки Шаг 1
Введите название название кнопки: Введите название название кнопки:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание названия кнопки. Шаг 2 Создание названия кнопки. Шаг 2
Введите описание название кнопки: Введите описание название кнопки:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание названия кнопки Создание названия кнопки
Загрузите обложку для названия кнопок (Фото): Загрузите обложку для названия кнопок (Фото):
На данный момент не поддерживается! На данный момент не поддерживается!
@ -95,23 +126,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите название кнопки, который вы хотите отредактировать. Выберите название кнопки, который вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для названия кнопок (Фото): Загрузите новую обложку для названия кнопок (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название названия кнопок: Текущее название названия кнопок:
#{name_field} #{name_field}
Введите новое название названия кнопки: Введите новое название названия кнопки:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание названия кнопок: Текущее описание названия кнопок:
#{desc_field} #{desc_field}
Введите новое описание названия кнопки: Введите новое описание названия кнопки:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к названию кнопки: Текущий доступ к названию кнопки:
#{access_field} #{access_field}
@ -127,8 +158,8 @@ messages = {
} }
class ModuleButtons(mod_table_operate.TableOperateModule): class ModuleButtons(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

70
bot_modules/comments.py

@ -3,9 +3,28 @@
# Комментарии # Комментарии
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message from bot_modules import mod_table_operate, mod_simple_message
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateComment(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditCommentPhotoItem(StatesGroup):
item_field = State()
class FSMEditCommentNameItem(StatesGroup):
item_field = State()
class FSMEditCommentDescItem(StatesGroup):
item_field = State()
class FSMEditCommentAccessItem(StatesGroup):
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'comments' module_name = 'comments'
@ -23,7 +42,7 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR), bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT), bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
@ -31,6 +50,14 @@ table = bd_table.Table(table_name, [
init_access = f'{user_access.user_access_group_new}=va' init_access = f'{user_access.user_access_group_new}=va'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateComment,
mod_table_operate.FSMs.EDIT_NAME: FSMEditCommentNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditCommentDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditCommentPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditCommentAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -39,10 +66,10 @@ button_names = {
mod_table_operate.ButtonNames.LIST: "📃 Список комментариев", mod_table_operate.ButtonNames.LIST: "📃 Список комментариев",
mod_table_operate.ButtonNames.ADD: "☑ Добавить комментарий", mod_table_operate.ButtonNames.ADD: "☑ Добавить комментарий",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать комментарий", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать комментарий",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение у комментария", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у комментария",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название у комментария", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у комментария",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание у комментария", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание у комментария",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к комментарию", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к комментарию",
mod_table_operate.ButtonNames.DEL: "❌ Удалить комментарий", mod_table_operate.ButtonNames.DEL: "❌ Удалить комментарий",
} }
@ -64,17 +91,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' mod_table_operate.Messages.CREATE_NAME: '''
Создание комментария. Шаг 1 Создание комментария. Шаг 1
Введите название комментария: Введите название комментария:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание комментария. Шаг 2 Создание комментария. Шаг 2
Введите описание комментария: Введите описание комментария:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание комментария. Шаг 3 Создание комментария. Шаг 3
Загрузите обложку для комментария (Фото): Загрузите обложку для комментария (Фото):
@ -87,23 +114,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите комментарий, который вы хотите отредактировать. Выберите комментарий, который вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для комментария (Фото): Загрузите новую обложку для комментария (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название комментария: Текущее название комментария:
#{name_field} #{name_field}
Введите новое название комментария: Введите новое название комментария:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание комментария: Текущее описание комментария:
#{desc_field} #{desc_field}
Введите новое описание комментария: Введите новое описание комментария:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к комментарийу: Текущий доступ к комментарийу:
#{access_field} #{access_field}
@ -118,22 +145,9 @@ messages = {
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Комментарий успешно удалён!''', mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Комментарий успешно удалён!''',
} }
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Комментарий создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Комментарий отредактирован''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Комментарий удалён''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Комментарий отредактирован #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Комментарий удалён #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Комментарий создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Комментарий отредактирован''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Комментарий удалён''',
}
messages.update(messages_subscribes)
class ModuleComments(mod_table_operate.TableOperateModule): class ModuleComments(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

210
bot_modules/groups.py

@ -1,136 +1,130 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> # Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Группы # Группы пользователей
from bot_sys import bot_bd, keyboard, user_access, bd_table from bot_sys import keyboard, user_access, bot_bd
from bot_modules import mod_table_operate, mod_simple_message from bot_modules import mod_simple_message
from bot_modules import access_utils, groups_utils from template import simple_message, sql_request, bd_item
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMRequestToBD(StatesGroup):
sqlRequest = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'groups' module_name = 'groups'
table_name = groups_utils.table_name table_groups_name = 'user_groups'
key_name = groups_utils.key_name table_user_in_groups_name = 'user_in_groups'
name_field = groups_utils.name_field
desc_field = groups_utils.desc_field
photo_field = groups_utils.photo_field
access_field = groups_utils.access_field
create_datetime_field = groups_utils.create_datetime_field
table_name_field = bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR)
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
table_name_field,
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
],
[
[table_name_field],
]
)
init_access = f'{user_access.user_access_group_new}=-' key_table_groups_name = 'group_id'
name_table_groups_field = 'groupName'
user_id_field = 'user_id'
access_field = 'access'
create_datetime_field = 'createDateTime'
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения
button_names = {
mod_simple_message.ButtonNames.START: "👥 Группы пользователей",
mod_table_operate.ButtonNames.LIST: "📃 Список групп",
mod_table_operate.ButtonNames.ADD: "✅ Добавить группу",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать группу",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в группе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в группе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в группе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к группе",
mod_table_operate.ButtonNames.DEL: "❌ Удалить группу",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''', request_start_message = '''
mod_table_operate.Messages.SELECT: ''' **Задайте запрос к БД**
Пожалуйста, выберите группу:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, группу не найден
''',
mod_table_operate.Messages.OPEN: f'''
<b>Группа: #{name_field}</b>
#{desc_field} Можете воспользоваться следующими шаблонами:
1. `SELECT * FROM users` - Все пользователи
Время создания: #{create_datetime_field} 2. `SELECT group_id, groupName FROM user_groups` - Все группы пользоватлей
''', 3. `INSERT INTO user_groups(groupName) VALUES('GROUPNAME')` - добавление группы с именем GROUPNAME
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' 4. `SELECT group_id FROM user_in_groups WHERE user_id = USERID`- Все ID групп в которых состоит пользователь с USERID
Создание группы. Шаг 1 5. `SELECT groupName FROM user_groups WHERE group_id=(SELECT groupid FROM user_in_groups WHERE user_id = USERID)` - Все имена групп пользователя с USERID
6. `INSERT INTO user_in_groups(user_id, group_id) VALUES(USERID, GROUPID)` - добавление пользователя USERID в группу с GROUPID
'''
Введите название группы: help_message = '''
''', 📄 Существует две БД для работы с группами
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' `user_groups (group_id, groupName)` - содержит названия групп
Создание группы. Шаг 2 `user_in_groups(user_id, group_id)` - содержит соответсвия ID пользователей и групп
'''
Введите описание группы: sql_request_button_name = "⛃ Запрос к БД для редактирования групп"
''', help_button_name = "📄 Информация по группам"
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): '''
Создание группы. Шаг 3
Загрузите обложку для группы (Фото): button_names = {
Она будет отображаться в его описании. mod_simple_message.ButtonNames.START: "▦ Группы пользователей",
''', }
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Группа успешно добавлена!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите группу, которого вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): '''
Загрузите новую обложку для группы (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f'''
Текущее название группы:
#{name_field}
Введите новое название группы: messages = {
''', mod_simple_message.Messages.START: '''
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' <b>Группы пользователей находятся в стадии разработки</b>
Текущее описание группы:
#{desc_field}
Введите новое описание группы: Пока можете воспользоваться хардкорным способом через запросы к БД
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' }
Текущий доступ к группе:
#{access_field}
{user_access.user_access_readme} init_access = f'{user_access.user_access_group_new}=-'
Введите новую строку доступа: class ModuleGroups(mod_simple_message.SimpleMessageModule):
''', def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Группа успешно отредактирована!''', super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
mod_table_operate.Messages.SELECT_TO_DELETE: ''' self.m_SqlRequestButtonName = self.CreateButton('sql request', sql_request_button_name)
Выберите группу, который вы хотите удалить. self.m_RequestStartMessage = self.CreateMessage('equest start', request_start_message)
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Группа успешно удалена!''', self.m_HelpButtonName = self.CreateButton('help', help_button_name)
} self.m_HelpMessage = self.CreateMessage('help', help_message)
self.m_HelpMessageHandler = simple_message.InfoMessageTemplate(
self.m_Bot,
self.m_HelpMessage,
self.m_GetStartKeyboardButtonsFunc,
None,
self.m_GetAccessFunc
)
class ModuleGroups(mod_table_operate.TableOperateModule): def GetInitBDCommands(self):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): return super(). GetInitBDCommands() + [
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) f"""CREATE TABLE IF NOT EXISTS {table_groups_name}(
{key_table_groups_name} INTEGER PRIMARY KEY NOT NULL,
{name_table_groups_field} TEXT,
{access_field} TEXT,
{create_datetime_field} TEXT,
UNIQUE({key_table_groups_name}),
UNIQUE({name_table_groups_field})
);""",
f"""CREATE TABLE IF NOT EXISTS {table_user_in_groups_name}(
{user_id_field} INTEGER,
{key_table_groups_name} INTEGER,
{access_field} TEXT,
{create_datetime_field} TEXT,
UNIQUE({user_id_field}, {key_table_groups_name})
);""",
f"INSERT OR IGNORE INTO {table_groups_name} ({name_table_groups_field}, {access_field}, {create_datetime_field}) VALUES ('{user_access.user_access_group_new}', '{user_access.user_access_group_new}=-', {bot_bd.GetBDDateTimeNow()});"
]
def GetName(self): def GetName(self):
return module_name return module_name
def GetInitBDCommands(self): def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
return super(). GetInitBDCommands() + [ mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
groups_utils.CreateGroupRequest(user_access.user_access_group_new) cur_buttons = [
keyboard.ButtonWithAccess(self.m_SqlRequestButtonName, user_access.AccessMode.EDIT, self.GetAccess()),
keyboard.ButtonWithAccess(self.m_HelpButtonName , user_access.AccessMode.VIEW, self.GetAccess())
] ]
return mod_buttons + keyboard.MakeButtons(cur_buttons, a_UserGroups)
def RegisterHandlers(self):
super().RegisterHandlers()
sql_request.RequestToBDRegisterHandlers(
self.m_Bot,
self.m_SqlRequestButtonName,
self.m_RequestStartMessage,
FSMRequestToBD,
self.m_GetStartKeyboardButtonsFunc,
user_access.AccessMode.EDIT,
self.m_GetAccessFunc
)
self.m_Bot.RegisterMessageHandler(
self.m_HelpMessageHandler,
bd_item.GetCheckForTextFunc(self.m_HelpButtonName)
)

22
bot_modules/groups_utils.py

@ -3,32 +3,14 @@
# Группы пользователей # Группы пользователей
from bot_sys import user_access, bot_bd from bot_sys import user_access
table_name = 'user_groups'
key_name = 'groupID'
name_field = 'groupName'
desc_field = 'groupDesc'
photo_field = 'groupPhoto'
access_field = 'groupAccess'
create_datetime_field = 'groupCreateDateTime'
table_user_in_groups_name = 'user_in_groups'
user_id_field = 'user_ID'
parent_id_field = 'groupID'
def GetUserGroupData(a_Bot, a_UserID): def GetUserGroupData(a_Bot, a_UserID):
def GetGroupNamesForUser(a_UserID): def GetGroupNamesForUser(a_UserID):
sql_req = f'SELECT {name_field} FROM {table_name} WHERE {key_name} IN (SELECT {parent_id_field} FROM {table_user_in_groups_name} WHERE {user_id_field} = ?)' return a_Bot.SQLRequest('SELECT groupName FROM user_groups WHERE group_id=(SELECT group_id FROM user_in_groups WHERE user_id = ?)', param = [a_UserID])
#print('GetGroupNamesForUser', sql_req)
return a_Bot.SQLRequest(sql_req, param = [a_UserID])
r = GetGroupNamesForUser(a_UserID) r = GetGroupNamesForUser(a_UserID)
groups = [] groups = []
for i in r: for i in r:
if len(i) > 0: if len(i) > 0:
groups += [i[0]] groups += [i[0]]
return user_access.UserGroups(a_UserID, groups) return user_access.UserGroups(a_UserID, groups)
def CreateGroupRequest(a_GroupName):
return f"INSERT OR IGNORE INTO {table_name} ({name_field}, {access_field}, {create_datetime_field}) VALUES ('{a_GroupName}', '{user_access.user_access_group_new}=-', {bot_bd.GetBDDateTimeNow()});"

55
bot_modules/languages.py

@ -7,6 +7,25 @@ from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message, access_utils from bot_modules import mod_table_operate, mod_simple_message, access_utils
from template import bd_item from template import bd_item
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateLanguage(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditLanguagePhotoItem(StatesGroup):
item_field = State()
class FSMEditLanguageNameItem(StatesGroup):
item_field = State()
class FSMEditLanguageDescItem(StatesGroup):
item_field = State()
class FSMEditLanguageAccessItem(StatesGroup):
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'languages' module_name = 'languages'
@ -25,7 +44,7 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
table_name_field, table_name_field,
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
], ],
@ -36,6 +55,14 @@ table = bd_table.Table(table_name, [
init_access = f'{user_access.user_access_group_all}=-' init_access = f'{user_access.user_access_group_all}=-'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateLanguage,
mod_table_operate.FSMs.EDIT_NAME: FSMEditLanguageNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditLanguageDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditLanguagePhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditLanguageAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -44,10 +71,10 @@ button_names = {
mod_table_operate.ButtonNames.LIST: "📃 Список языков", mod_table_operate.ButtonNames.LIST: "📃 Список языков",
mod_table_operate.ButtonNames.ADD: "✅ Добавить язык", mod_table_operate.ButtonNames.ADD: "✅ Добавить язык",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать язык", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать язык",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в языке", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение в языке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в языке", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название в языке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в языке", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание в языке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к языку", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к языку",
mod_table_operate.ButtonNames.DEL: "❌ Удалить язык", mod_table_operate.ButtonNames.DEL: "❌ Удалить язык",
} }
@ -69,17 +96,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' mod_table_operate.Messages.CREATE_NAME: '''
Создание языка. Шаг 1 Создание языка. Шаг 1
Введите название языка: Введите название языка:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание языка. Шаг 2 Создание языка. Шаг 2
Введите описание языка: Введите описание языка:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание языка. Шаг 3 Создание языка. Шаг 3
Загрузите обложку для языка (Фото): Загрузите обложку для языка (Фото):
@ -92,23 +119,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите язык, который вы хотите отредактировать. Выберите язык, который вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для языка (Фото): Загрузите новую обложку для языка (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название языка: Текущее название языка:
#{name_field} #{name_field}
Введите новое название языка: Введите новое название языка:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание языка: Текущее описание языка:
#{desc_field} #{desc_field}
Введите новое описание языка: Введите новое описание языка:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к языку: Текущий доступ к языку:
#{access_field} #{access_field}
@ -125,8 +152,8 @@ messages = {
} }
class ModuleLanguages(mod_table_operate.TableOperateModule): class ModuleLanguages(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
self.m_LanguageIDs = {} self.m_LanguageIDs = {}
def GetName(self): def GetName(self):

84
bot_modules/messages.py

@ -7,6 +7,29 @@ from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_messages
from bot_modules import mod_table_operate, mod_simple_message, access_utils from bot_modules import mod_table_operate, mod_simple_message, access_utils
from template import bd_item from template import bd_item
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateMessage(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditMessagePhotoItem(StatesGroup):
item_id = State()
item_field = State()
class FSMEditMessageNameItem(StatesGroup):
item_id = State()
item_field = State()
class FSMEditMessageDescItem(StatesGroup):
item_id = State()
item_field = State()
class FSMEditMessageAccessItem(StatesGroup):
item_id = State()
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'messages' module_name = 'messages'
@ -27,7 +50,7 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
table_name_field, table_name_field,
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
table_parent_id_field, table_parent_id_field,
@ -39,6 +62,14 @@ table = bd_table.Table(table_name, [
init_access = f'{user_access.user_access_group_all}=-' init_access = f'{user_access.user_access_group_all}=-'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateMessage,
mod_table_operate.FSMs.EDIT_NAME: FSMEditMessageNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditMessageDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditMessagePhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditMessageAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -46,11 +77,11 @@ button_names = {
mod_simple_message.ButtonNames.START: "✉ Сообщения", mod_simple_message.ButtonNames.START: "✉ Сообщения",
mod_table_operate.ButtonNames.LIST: "📃 Список сообщений", mod_table_operate.ButtonNames.LIST: "📃 Список сообщений",
mod_table_operate.ButtonNames.ADD: "☑ Добавить сообщение", mod_table_operate.ButtonNames.ADD: "☑ Добавить сообщение",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать сообщение бота", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать сообщение",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение у сообщения", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): " Изменить название сообщения", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание сообщения", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): " Изменить доступ к сообщению", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к сообщению",
mod_table_operate.ButtonNames.DEL: "❌ Удалить сообщение", mod_table_operate.ButtonNames.DEL: "❌ Удалить сообщение",
} }
@ -72,20 +103,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.CREATE_NAME: '''
Создание сообщения. Шаг 1 Создание сообщения. Шаг 1
Вы можете добавить номер родителя ID в таком формате: ИмяСообщения{'<code>?' + str(bd_table.TableFieldDestiny.PARENT_ID) + '=</code>ID'}
, чтобы сообщение было только для него
Введите название сообщения: Введите название сообщения:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание сообщения. Шаг 2 Создание сообщения. Шаг 2
Введите описание сообщения: Введите описание сообщения:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание сообщения. Шаг 3 Создание сообщения. Шаг 3
Загрузите обложку для сообщения (Фото): Загрузите обложку для сообщения (Фото):
@ -98,23 +126,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите сообщение, который вы хотите отредактировать. Выберите сообщение, который вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для сообщения (Фото): Загрузите новую обложку для сообщения (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название сообщения: Текущее название сообщения:
#{name_field} #{name_field}
Введите новое название сообщения: Введите новое название сообщения:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание сообщения: Текущее описание сообщения:
#{desc_field} #{desc_field}
Введите новое описание сообщения: Введите новое описание сообщения:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к сообщениеу: Текущий доступ к сообщениеу:
#{access_field} #{access_field}
@ -130,8 +158,8 @@ messages = {
} }
class ModuleMessages(mod_table_operate.TableOperateModule): class ModuleMessages(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name
@ -149,7 +177,12 @@ class ModuleMessages(mod_table_operate.TableOperateModule):
return self.m_Bot.SQLRequest(f'INSERT OR IGNORE INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {parent_id_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})', return self.m_Bot.SQLRequest(f'INSERT OR IGNORE INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {parent_id_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})',
commit = True, return_error = True, param = (a_Message.m_PhotoID, a_Message.m_MessageName, a_Message.m_MessageDesc, access_utils.GetItemDefaultAccessForModule(self.m_Bot, module_name), lang_id)) commit = True, return_error = True, param = (a_Message.m_PhotoID, a_Message.m_MessageName, a_Message.m_MessageDesc, access_utils.GetItemDefaultAccessForModule(self.m_Bot, module_name), lang_id))
def LoadAllMessages(self): def FlushMessages(self):
msg = self.m_BotMessages.GetMessages()
for lang, msg_dict in msg.items():
for msg_name, message in msg_dict.items():
self.AddOrIgnoreMessage(message)
table_name = self.m_Table.GetName() table_name = self.m_Table.GetName()
msgs_bd = bd_item.GetAllItemsTemplate(self.m_Bot, table_name)() msgs_bd = bd_item.GetAllItemsTemplate(self.m_Bot, table_name)()
if msgs_bd: if msgs_bd:
@ -161,20 +194,7 @@ class ModuleMessages(mod_table_operate.TableOperateModule):
lang_name = self.GetModule(self.m_ParentModName).GetLangName(lang_id) lang_name = self.GetModule(self.m_ParentModName).GetLangName(lang_id)
self.m_BotMessages.CreateMessage(name, desc, self.m_Log.GetTimeNow(), a_MessagePhotoID = photo_id, a_MessageLang = lang_name) self.m_BotMessages.CreateMessage(name, desc, self.m_Log.GetTimeNow(), a_MessagePhotoID = photo_id, a_MessageLang = lang_name)
def FlushMessages(self):
msg = self.m_BotMessages.GetMessages()
for lang, msg_dict in msg.items():
for msg_name, message in msg_dict.items():
self.AddOrIgnoreMessage(message)
self.LoadAllMessages()
self.m_BotMessages.UpdateSignal(self.m_Log.GetTimeNow()) self.m_BotMessages.UpdateSignal(self.m_Log.GetTimeNow())
def OnChange(self): def OnChange(self):
self.FlushMessages() self.FlushMessages()
async def PostDelete(self, a_CallbackQuery, a_ItemID):
self.LoadAllMessages() # Сначала загружаем, т.к. одно сообщение удалилось
await super().PostDelete(a_CallbackQuery, a_ItemID)

22
bot_modules/mod_simple_message.py

@ -17,15 +17,13 @@ class Messages(Enum):
START = auto() START = auto()
class SimpleMessageModule(mod_interface.IModule): class SimpleMessageModule(mod_interface.IModule):
def __init__(self, a_Messages, a_Buttons, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_Messages, a_Buttons, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
self.m_ChildModuleNameList = a_ChildModuleNameList self.m_ChildModuleNameList = a_ChildModuleNameList
self.m_InitAccess = a_InitAccess self.m_InitAccess = a_InitAccess
self.m_DefInitAccess = a_DefInitAccess
self.m_Bot = a_Bot self.m_Bot = a_Bot
self.m_ModuleAgregator = a_ModuleAgregator self.m_ModuleAgregator = a_ModuleAgregator
self.m_BotMessages = a_BotMessages self.m_BotMessages = a_BotMessages
self.m_BotButtons = a_BotButtons self.m_BotButtons = a_BotButtons
self.m_BotSubscribes = a_BotSubscribes
self.m_Log = a_Log self.m_Log = a_Log
self.m_Buttons = {} self.m_Buttons = {}
@ -67,18 +65,14 @@ class SimpleMessageModule(mod_interface.IModule):
return self.m_Messages.get(a_MessageNames, None) return self.m_Messages.get(a_MessageNames, None)
def CreateMessage(self, a_MessageName, a_MessageDesc): def CreateMessage(self, a_MessageName, a_MessageDesc):
msg = self.m_BotMessages.CreateMessage(f'{self.GetName()} {str(a_MessageName).replace("Messages.", "")}', a_MessageDesc, self.m_Log.GetTimeNow()) msg = self.m_BotMessages.CreateMessage(f'{self.GetName()} {a_MessageName}', a_MessageDesc, self.m_Log.GetTimeNow())
return msg return msg
def CreateButton(self, a_ButtonName, a_ButtonDesc): def CreateButton(self, a_ButtonName, a_ButtonDesc):
if len(a_ButtonDesc) >= 41: assert len(a_ButtonDesc) < 41 # Телеграм не поддерживает больше
print('ButtonDesc:', a_ButtonDesc) assert a_ButtonDesc[0] != ' ' # Телеграм не поддерживает пробелы в начале
assert False # Телеграм не поддерживает больше assert a_ButtonDesc[-1:] != ' ' # Телеграм не поддерживает пробелы в конце
assert a_ButtonDesc[0] != ' ', f'ButtonDesc:{a_ButtonDesc}, Телеграм не поддерживает пробелы в начале' btn = self.m_BotButtons.CreateMessage(f'{self.GetName()} {a_ButtonName}', a_ButtonDesc, self.m_Log.GetTimeNow())
assert a_ButtonDesc[-1:] != ' ', f'ButtonDesc:{a_ButtonDesc}, Телеграм не поддерживает пробелы в конце'
btn_name = f'{self.GetName()} {str(a_ButtonName).replace("ButtonNames.", "")}'
assert not self.m_BotButtons.CheckDescExist(a_ButtonDesc), f'ButtonDesc:{a_ButtonDesc}, повтор имени кнопки, все кнопки должны быть разными'
btn = self.m_BotButtons.CreateMessage(btn_name, a_ButtonDesc, self.m_Log.GetTimeNow())
return btn return btn
def GetModule(self, a_ModName): def GetModule(self, a_ModName):
@ -86,8 +80,6 @@ class SimpleMessageModule(mod_interface.IModule):
def GetButtons(self, a_ModNameList): def GetButtons(self, a_ModNameList):
buttons = [] buttons = []
if not a_ModNameList:
return buttons
for n in a_ModNameList: for n in a_ModNameList:
m = self.m_ModuleAgregator.GetModule(n) m = self.m_ModuleAgregator.GetModule(n)
b = m.GetModuleButtons() b = m.GetModuleButtons()
@ -101,7 +93,7 @@ class SimpleMessageModule(mod_interface.IModule):
def GetInitBDCommands(self): def GetInitBDCommands(self):
return [ return [
access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_DefInitAccess), access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_InitAccess),
] ]
def GetAccess(self): def GetAccess(self):

681
bot_modules/mod_table_operate.py

@ -3,118 +3,60 @@
# Модуль для редактирования и просмотра таблицы в БД # Модуль для редактирования и просмотра таблицы в БД
from bot_sys import keyboard, user_access, bd_table, bot_bd, bot_subscribes from bot_sys import keyboard, user_access, bd_table, bot_bd
from bot_modules import access_utils, mod_simple_message, groups_utils from bot_modules import access_utils, mod_simple_message
from template import simple_message, bd_item, bd_item_select, bd_item_view, bd_item_delete, bd_item_add, bd_item_edit from template import simple_message, bd_item, bd_item_select, bd_item_view, bd_item_delete, bd_item_add, bd_item_edit
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from enum import Enum from enum import Enum
from enum import auto from enum import auto
def EditButton(a_BDTableDestiny):
return 'edit ' + str(a_BDTableDestiny)
def EnumButton(a_EnumItem):
return 'enum ' + str(a_EnumItem)
def EditMessage(a_BDTableDestiny):
return 'edit ' + str(a_BDTableDestiny)
def InlineMessage(a_ButtonName):
return 'inline ' + str(a_ButtonName)
def CreateMessage(a_BDTableDestiny):
return 'create ' + str(a_BDTableDestiny)
def EnumMessageForView(a_EnumItem):
return 'enum ' + str(a_EnumItem)
def NotificationMessage(a_EnumItem):
return 'notification ' + str(a_EnumItem)
def SubscribeMessage(a_EnumItem):
return 'subscribe ' + str(a_EnumItem)
class ButtonNames(Enum): class ButtonNames(Enum):
SHOW = auto()
LIST = auto() LIST = auto()
ADD = auto() ADD = auto()
EDIT = auto() EDIT = auto()
EDIT_PHOTO = auto()
EDIT_NAME = auto()
EDIT_DESC = auto()
EDIT_ACCESS = auto()
EDIT_DEFAULT_ACCESS = auto()
DEL = auto() DEL = auto()
class Messages(Enum): class Messages(Enum):
SELECT = auto() SELECT = auto()
ERROR_FIND = auto() ERROR_FIND = auto()
OPEN = auto() OPEN = auto()
CREATE_NAME = auto()
CREATE_DESC = auto()
CREATE_PHOTO = auto()
SUCCESS_CREATE = auto() SUCCESS_CREATE = auto()
START_EDIT = auto() START_EDIT = auto()
SELECT_TO_EDIT = auto() SELECT_TO_EDIT = auto()
EDIT_PHOTO = auto()
EDIT_NAME = auto()
EDIT_DESC = auto()
EDIT_ACCESS = auto()
EDIT_DEFAULT_ACCESS = auto()
SUCCESS_EDIT = auto() SUCCESS_EDIT = auto()
SELECT_TO_DELETE = auto() SELECT_TO_DELETE = auto()
SUCCESS_DELETE = auto() SUCCESS_DELETE = auto()
def GetCurItem(a_Bot, a_TableName, a_KeyName, a_KeyValue): class FSMs(Enum):
items = bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_KeyName)(a_KeyValue) CREATE = auto()
if len(items) == 1: EDIT_PHOTO = auto()
return items[0] EDIT_NAME = auto()
return None EDIT_DESC = auto()
EDIT_ACCESS = auto()
create_fsm_create_cmd = ''' EDIT_DEFAULT_ACCESS = auto()
class FSMCreate{a_ModName}(StatesGroup):
{items}
fsm = FSMCreate{a_ModName}
'''
def MakeFSMForAdd(a_ModName, a_Fields):
cmd = create_fsm_create_cmd.replace("{a_ModName}", a_ModName)
items = ""
for i in range(len(a_Fields)):
items += f"\titem{i} = State()\n"
cmd = cmd.replace("{items}", items)
_locals = locals()
exec(cmd, globals(), _locals)
return _locals['fsm']
edit_fsm_cmd = '''
class FSMEdit{a_ModName}_{a_FieldName}_Item(StatesGroup):
item_field = State()
fsm = FSMEdit{a_ModName}_{a_FieldName}_Item
'''
def MakeFSMForEdit(a_ModName, a_FieldName):
cmd = edit_fsm_cmd.replace("{a_ModName}", a_ModName).replace("{a_FieldName}", a_FieldName)
_locals = locals()
exec(cmd, globals(), _locals)
return _locals['fsm']
add_and_edit_fsm_cmd = '''
class FSMAddAndEdit{a_ModName}_{a_FieldName}_Item(StatesGroup):
item_field = State()
fsm = FSMAddAndEdit{a_ModName}_{a_FieldName}_Item
'''
def MakeFSMForAddAndEdit(a_ModName, a_FieldName):
cmd = add_and_edit_fsm_cmd.replace("{a_ModName}", a_ModName).replace("{a_FieldName}", a_FieldName)
_locals = locals()
exec(cmd, globals(), _locals)
return _locals['fsm']
class TableOperateModule(mod_simple_message.SimpleMessageModule): class TableOperateModule(mod_simple_message.SimpleMessageModule):
def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_Table, a_Messages, a_Buttons, a_FSMs, a_ParentModName, a_ChildModName, a_InitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(a_Messages, a_Buttons, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(a_Messages, a_Buttons, a_InitAccess, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
self.m_Table = a_Table self.m_Table = a_Table
self.m_FSMs = a_FSMs
self.m_EditModuleNameList = a_EditModuleNameList self.m_EditModuleNameList = a_EditModuleNameList
self.m_ChildModName = a_ChildModName self.m_ChildModName = a_ChildModName
self.m_ParentModName = a_ParentModName self.m_ParentModName = a_ParentModName
self.m_SelectPrefix = '' self.m_SelectPrefix = ''
self.m_EditPrefix = {}
def GetEditKeyboardButtons(a_Message, a_UserGroups): def GetEditKeyboardButtons(a_Message, a_UserGroups):
return self.GetEditKeyboardButtons(a_Message, a_UserGroups) return self.GetEditKeyboardButtons(a_Message, a_UserGroups)
@ -124,58 +66,47 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
return self.GetButtonNameAndKeyValueAndAccess(a_Item) return self.GetButtonNameAndKeyValueAndAccess(a_Item)
self.m_GetButtonNameAndKeyValueAndAccessFunc = GetButtonNameAndKeyValueAndAccess self.m_GetButtonNameAndKeyValueAndAccessFunc = GetButtonNameAndKeyValueAndAccess
async def PreDelete(a_CallbackQuery, a_Item, a_None, table_name = self.m_Table.GetName()): async def PreDelete(a_CallbackQuery, a_Item):
return await self.PreDelete(a_CallbackQuery, a_Item, a_None) return await self.PreDelete(a_CallbackQuery, a_Item)
self.m_PreDeleteFunc = PreDelete self.m_PreDeleteFunc = PreDelete
async def PostDelete(a_CallbackQuery, a_ItemID): async def PostDelete(a_CallbackQuery, a_ItemID):
return await self.PostDelete(a_CallbackQuery, a_ItemID) return await self.PostDelete(a_CallbackQuery, a_ItemID)
self.m_PostDeleteFunc = PostDelete self.m_PostDeleteFunc = PostDelete
async def AddBDItemFunc(a_ItemData, a_UserID): def AddBDItemFunc(a_ItemData, a_UserID):
return await self.AddBDItemFunc(a_ItemData, a_UserID) return self.AddBDItemFunc(a_ItemData, a_UserID)
self.m_AddBDItemFunc = AddBDItemFunc self.m_AddBDItemFunc = AddBDItemFunc
def GetFSM(self, a_FSMName):
return self.m_FSMs.get(a_FSMName, None)
def GetInitBDCommands(self): def GetInitBDCommands(self):
return [ return super(). GetInitBDCommands() + [
self.m_Table.GetInitTableRequest(), self.m_Table.GetInitTableRequest(),
] + super().GetInitBDCommands()
def GetStartButtons(self, a_Message, a_UserGroups):
return [
[ButtonNames.LIST, user_access.AccessMode.VIEW],
[ButtonNames.ADD, user_access.AccessMode.ADD],
[ButtonNames.DEL, user_access.AccessMode.DELETE],
[ButtonNames.EDIT, user_access.AccessMode.EDIT],
] ]
def GetStartKeyboardButtons(self, a_Message, a_UserGroups): def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups) mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
cur_buttons = [] cur_buttons = [
for b in self.GetStartButtons(a_Message, a_UserGroups): keyboard.ButtonWithAccess(self.GetButton(ButtonNames.LIST), user_access.AccessMode.VIEW, self.GetAccess()),
bn = b[0] keyboard.ButtonWithAccess(self.GetButton(ButtonNames.ADD), user_access.AccessMode.ADD, self.GetAccess()),
ba = b[1] keyboard.ButtonWithAccess(self.GetButton(ButtonNames.DEL), user_access.AccessMode.DELETE, self.GetAccess()),
cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(bn), ba, self.GetAccess())] keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT), user_access.AccessMode.EDIT, self.GetAccess()),
]
return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
def GetAccessForEditKeyboardButtons(self, a_Field):
if a_Field.m_Destiny == bd_table.TableFieldDestiny.ACCESS or a_Field.m_Destiny == bd_table.TableFieldDestiny.DEFAULT_ACCESS:
return user_access.AccessMode.ACCEES_EDIT
return user_access.AccessMode.EDIT
def GetEditKeyboardButtons(self, a_Message, a_UserGroups): def GetEditKeyboardButtons(self, a_Message, a_UserGroups):
mod_buttons = keyboard.MakeButtons(self.m_Bot, self.GetButtons(self.m_EditModuleNameList), a_UserGroups) mod_buttons = keyboard.MakeButtons(self.m_Bot, self.GetButtons(self.m_EditModuleNameList), a_UserGroups)
cur_buttons = [] cur_buttons = [
for f in self.m_Table.GetFields(): keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_PHOTO), user_access.AccessMode.VIEW, self.GetAccess()),
access = self.GetAccessForEditKeyboardButtons(f) keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_NAME), user_access.AccessMode.ADD, self.GetAccess()),
cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EditButton(f.m_Destiny)), access, self.GetAccess()),] keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_DESC), user_access.AccessMode.DELETE, self.GetAccess()),
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_ACCESS), user_access.AccessMode.DELETE, self.GetAccess()),
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.EDIT_DEFAULT_ACCESS), user_access.AccessMode.EDIT, self.GetAccess()),
]
return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
def GetShowItemInlineKeyboardTemplate(self, a_ItemID):
def GetShowItemInlineKeyboard(a_Message, a_UserGroups):
return self.GetShowItemInlineKeyboard(a_Message, a_UserGroups, a_ItemID)
return GetShowItemInlineKeyboard
def GetViewItemInlineKeyboardTemplate(self, a_ItemID): def GetViewItemInlineKeyboardTemplate(self, a_ItemID):
def GetViewItemInlineKeyboard(a_Message, a_UserGroups): def GetViewItemInlineKeyboard(a_Message, a_UserGroups):
return self.GetViewItemInlineKeyboard(a_Message, a_UserGroups, a_ItemID) return self.GetViewItemInlineKeyboard(a_Message, a_UserGroups, a_ItemID)
@ -184,162 +115,64 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
def GetSelectPrefix(self): def GetSelectPrefix(self):
return self.m_SelectPrefix return self.m_SelectPrefix
def GetDelPrefix(self):
return self.m_DelPrefix
def GetAddPrefix(self):
return self.m_AddPrefix
def GetShowPrefix(self):
return self.m_ShowPrefix
def GetShowItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID):
cur_buttons = [
keyboard.InlineButtonWithAccess(self.GetButton(ButtonNames.SHOW), self.GetShowPrefix(), a_ItemID, self.GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups)
def GetViewItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID): def GetViewItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID):
if not self.m_ChildModName: if not self.m_ChildModName:
return None return None
child_mod = self.GetModule(self.m_ChildModName) child_mod = self.GetModule(self.m_ChildModName)
cur_buttons = [ cur_buttons = [
keyboard.InlineButtonWithAccess(child_mod.GetButton(ButtonNames.LIST), child_mod.GetSelectPrefix(), a_ItemID, child_mod.GetAccess(), user_access.AccessMode.VIEW), keyboard.InlineButtonWithAccess(child_mod.GetButton(ButtonNames.LIST), child_mod.GetSelectPrefix(), a_ItemID, self.GetAccess(), user_access.AccessMode.VIEW),
] ]
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups) return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups)
def GetButtonNameAndKeyValueAndAccess(self, a_Item): def GetButtonNameAndKeyValueAndAccess(self, a_Item):
key_name_id = self.GetKeyFieldID()
name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME)
access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)
assert key_name_id != None
assert name_field_id != None
assert access_field_id != None
return \ return \
a_Item[name_field_id],\ a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME)],\
a_Item[key_name_id],\ a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)],\
a_Item[access_field_id] a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)]
def UpdateMessage(self, a_Msg, a_Lang, a_Item, a_EnablePhoto = False): def ShowMessageTemplate(self, a_Message, Inline_keyboard_template_func = None):
a_Msg.UpdateDesc(self.m_Table.ReplaceAllFieldTags(a_Msg.GetDesc(), a_Item)) async def ShowMessage(a_CallbackQuery, a_Item):
photos = [] msg = a_Message.StaticCopy()
field_id = 0 # TODO: добавить поддержку языка в a_MessageName
for f in self.m_Table.GetFields():
if f.m_Type == bd_table.TableFieldType.ENUM:
for s in f.m_Enum:
msg = self.GetMessage(EnumMessageForView(s))
if msg:
a_Msg.UpdateDesc(a_Msg.GetDesc().replace(str(s), str(msg.GetMessageForLang(a_Lang).StaticCopy())))
elif f.m_Type == bd_table.TableFieldType.PHOTO:
photos += [str(a_Item[field_id])]
field_id += 1
if a_EnablePhoto:
a_Msg.UpdatePhotoID(','.join(photos))
return a_Msg
def UpdateMessageByDict(self, a_Msg, a_Lang, a_ItemDict, a_EnablePhoto = False):
a_Msg.UpdateDesc(self.m_Table.ReplaceAllFieldTagsByDict(a_Msg.GetDesc(), a_ItemDict))
photos = []
for f in self.m_Table.GetFields():
if f.m_Type == bd_table.TableFieldType.ENUM:
for s in f.m_Enum:
msg = self.GetMessage(EnumMessageForView(s))
if msg:
a_Msg.UpdateDesc(a_Msg.GetDesc().replace(str(s), str(msg.GetMessageForLang(a_Lang).StaticCopy())))
elif f.m_Type == bd_table.TableFieldType.PHOTO:
if f.m_Name in a_ItemDict:
photos += [str(a_ItemDict[f.m_Name])]
if a_EnablePhoto:
a_Msg.UpdatePhotoID(','.join(photos))
return a_Msg
def GetParentID(self, a_Item, a_ItemDict, a_TableName):
parent_id = None
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
if parent_id_field and a_ItemDict and parent_id_field in a_ItemDict:
parent_id = str(a_ItemDict[parent_id_field])
parent_id_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
if not parent_id and parent_id_field_id != None and a_Item and len(a_Item) == self.m_Table.GetFieldsCount() and self.m_Table.GetName() == a_TableName:
parent_id = str(a_Item[parent_id_field_id])
if self.m_ParentModName:
parent_mod = self.GetModule(self.m_ParentModName)
if parent_mod:
key_field_id = parent_mod.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)
if not parent_id and key_field_id != None and a_Item and len(a_Item) == parent_mod.m_Table.GetFieldsCount() and parent_mod.m_Table.GetName() == a_TableName:
parent_id = str(a_Item[key_field_id])
return parent_id
def GetMessageNameWithTableFieldDestinyAndValue(self, a_NameWithoutDestiny, a_Destiny, a_Value):
return a_NameWithoutDestiny + '?' + str(a_Destiny) + '=' + str(a_Value)
def ShowMessageTemplate(self, a_Message, Inline_keyboard_template_func = None, a_EnablePhoto = False):
async def ShowMessage(a_CallbackQuery, a_Item, a_ItemDict, table_name = self.m_Table.GetName()):
lang = str(a_CallbackQuery.from_user.language_code)
msg = a_Message
# Подменяем сообщение, если оно уже есть для PARENT_ID
parent_id = self.GetParentID(a_Item, a_ItemDict, table_name)
if parent_id:
name = self.GetMessageNameWithTableFieldDestinyAndValue(msg.GetName(), bd_table.TableFieldDestiny.PARENT_ID, parent_id)
parent_id_msg = a_Message.FindMessageForLang(name, lang)
if parent_id_msg:
msg = parent_id_msg
msg = msg.GetMessageForLang(lang).StaticCopy()
# TODO: добавить поддержку языков в a_MessageName
Inline_keyboard_func = None Inline_keyboard_func = None
item_access = None item_access = None
if a_ItemDict: if a_Item:
msg = self.UpdateMessageByDict(msg, lang, a_ItemDict, a_EnablePhoto = a_EnablePhoto)
if a_Item and self.m_Table.GetName() == table_name:
if len(a_Item) < self.m_Table.GetFieldsCount() - 1: # Для проектов это нужно. Там на 1 меньше поле. TODO разделить отправку сообщений item_access и Inline_keyboard_func if len(a_Item) < self.m_Table.GetFieldsCount() - 1: # Для проектов это нужно. Там на 1 меньше поле. TODO разделить отправку сообщений item_access и Inline_keyboard_func
return simple_message.WorkFuncResult(self.GetMessage(Messages.ERROR_FIND)) return simple_message.WorkFuncResult(self.GetMessage(Messages.ERROR_FIND))
elif len(a_Item) == self.m_Table.GetFieldsCount(): elif len(a_Item) == self.m_Table.GetFieldsCount():
msg = self.UpdateMessage(msg, lang, a_Item, a_EnablePhoto = a_EnablePhoto) lang = str(a_CallbackQuery.from_user.language_code)
msg = msg.GetMessageForLang(lang).StaticCopy()
msg.UpdateDesc(self.m_Table.ReplaceAllFieldTags(msg.GetDesc(), a_Item))
photo_field = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PHOTO)
if photo_field:
msg.UpdatePhotoID(a_Item[photo_field])
item_access = a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)] item_access = a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)]
if Inline_keyboard_template_func: if Inline_keyboard_template_func:
Inline_keyboard_func = Inline_keyboard_template_func(a_Item[self.GetKeyFieldID()]) Inline_keyboard_func = Inline_keyboard_template_func(a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)])
return simple_message.WorkFuncResult(msg, item_access = item_access, Inline_keyboard_func = Inline_keyboard_func) return simple_message.WorkFuncResult(msg, item_access = item_access, Inline_keyboard_func = Inline_keyboard_func)
return ShowMessage return ShowMessage
async def PreDelete(self, a_CallbackQuery, a_Item, a_None): # TODO: delete?
def SimpleMessageTemplate(self, a_MessageName : Messages):
async def ShowMessage(a_CallbackQuery, a_Item):
return simple_message.WorkFuncResult(self.GetMessage(a_MessageName))
return ShowMessage
async def PreDelete(self, a_CallbackQuery, a_Item):
if len(a_Item) < self.m_Table.GetFieldsCount(): if len(a_Item) < self.m_Table.GetFieldsCount():
return simple_message.WorkFuncResult(self.GetMessage(Messages.ERROR_FIND)) return simple_message.WorkFuncResult(error_find_proj_message)
access = a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)] access = a_Item[self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)]
return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE), None, item_access = access) return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE), None, item_access = access)
async def PostDelete(self, a_CallbackQuery, a_ItemID): async def PostDelete(self, a_CallbackQuery, a_ItemID):
user_id = a_CallbackQuery.from_user.id self.m_Log.Success(f'Задача №{a_ItemID} была удалена пользователем {a_CallbackQuery.from_user.id}.')
self.m_Log.Success(f'Элемент №{a_ItemID} была удалена пользователем {user_id}.')
#TODO: удалить вложенные #TODO: удалить вложенные
self.OnChange() self.OnChange()
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_DEL
item_id = -1
await self.SendSubscribe(subscribe_type, item_id, user_id, item_id)
subscribe_type = bot_subscribes.SubscribeType.ITEM_DEL
item_id = a_ItemID
await self.SendSubscribe(subscribe_type, item_id, user_id, item_id)
table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName()
cur_item = GetCurItem(self.m_Bot, table_name, key_name, a_ItemID)
parent_id_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
if parent_id_field_index and cur_item and cur_item[parent_id_field_index]:
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT
item_id = cur_item[parent_id_field_index]
await self.SendSubscribe(subscribe_type, item_id, user_id, item_id)
return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE)) return simple_message.WorkFuncResult(self.GetMessage(Messages.SUCCESS_DELETE))
async def AddBDItemFunc(self, a_ItemData, a_UserID): def AddBDItemFunc(self, a_ItemData, a_UserID):
table_name = self.m_Table.GetName() table_name = self.m_Table.GetName()
key_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME) name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME)
photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO) photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO)
desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC) desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC)
@ -347,276 +180,59 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE) create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE)
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
res, error = None, None
def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName()) def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName())
#TODO сделать список полей, чтобы запрос генерировался автоматически.
fields = [] if parent_id_field:
values = [] res, error = self.m_Bot.SQLRequest(f'INSERT INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {parent_id_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})',
param = () commit = True, return_error = True, param = (a_ItemData[photo_field], a_ItemData[name_field], a_ItemData[desc_field], def_access + f";{a_UserID}=+", a_ItemData[parent_id_field]))
for f in self.m_Table.GetFields():
d = f.m_Destiny
n = f.m_Name
if d == bd_table.TableFieldDestiny.KEY:
continue
elif d == bd_table.TableFieldDestiny.CREATE_DATE:
fields += [n]
values += [bot_bd.GetBDDateTimeNow()]
elif d == bd_table.TableFieldDestiny.ACCESS:
fields += [n]
values += ['?']
param += (def_access + f";{a_UserID}=+", )
else: else:
fields += [n] res, error = self.m_Bot.SQLRequest(f'INSERT INTO {table_name}({photo_field}, {name_field}, {desc_field}, {access_field}, {create_datetime_field}) VALUES(?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()})',
values += ['?'] commit = True, return_error = True, param = (a_ItemData[photo_field], a_ItemData[name_field], a_ItemData[desc_field], def_access + f";{a_UserID}=+"))
param += (a_ItemData[n], )
request = f'INSERT INTO {table_name}({",".join(fields)}) VALUES({",".join(values)})' # RETURNING {key_field}
#print('request', request, param)
res, error = self.m_Bot.SQLRequest(request, commit = True, return_error = True, param = param)
self.OnChange() self.OnChange()
if error: if error:
self.m_Log.Error(f'Пользователь {a_UserID}. Ошибка добавления записи в таблицу {request} {param}.') self.m_Log.Error(f'Пользоватлель {a_UserID}. Ошибка добавления записи в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {def_access}).')
else: else:
self.m_Log.Success(f'Пользователь {a_UserID}. Добавлена запись в таблицу {request} {param}.') self.m_Log.Success(f'Пользоватлель {a_UserID}. Добавлена запись в таблицу {table_name} ({a_ItemData[photo_field]}, {a_ItemData[name_field]}, {a_ItemData[desc_field]}, {def_access}).')
res_id, error_id = self.m_Bot.SQLRequest(f'SELECT rowid from {table_name} order by ROWID DESC limit 1', commit = False, return_error = True)
table_item_id = -1
if not error_id and res_id and len(res_id) == 1 and len(res_id[0]) == 1:
table_item_id = str(res_id[0][0])
#print('res_id', res, error, table_item_id)
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_ADD
item_id = -1
await self.SendSubscribe(subscribe_type, item_id, a_UserID, table_item_id)
if parent_id_field and a_ItemData[parent_id_field]:
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT
item_id = a_ItemData[parent_id_field]
await self.SendSubscribe(subscribe_type, item_id, a_UserID, table_item_id)
return res, error return res, error
async def SendMessageToUser(self, a_Message, a_UserID, a_GetButtonsFunc = None, a_GetInlineButtonsFunc = None, parse_mode = None):
a_Message = a_Message.StaticCopy()
a_MessageFromUSer = None
user_groups = groups_utils.GetUserGroupData(self.m_Bot, a_UserID)
try:
#print('SendMessage', self.m_Bot, a_Message, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_UserID, a_MessageFromUSer, user_groups, parse_mode)
await simple_message.SendMessage(self.m_Bot, a_Message, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_UserID, a_MessageFromUSer, user_groups, parse_mode=parse_mode)
return True
except:
return False
async def SendSubscribe(self, a_Type, a_ItemID, a_OwnerUserID, a_TableItem):
table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName()
cur_item = GetCurItem(self.m_Bot, table_name, key_name, a_TableItem)
for s_user_id in self.m_BotSubscribes.GetUserIDs(self.GetName(), a_Type, a_ItemID = a_ItemID):
a_BotMessage = self.GetMessage(SubscribeMessage(a_Type))
#print('s_user_id', s_user_id, a_BotMessage, a_OwnerUserID, a_TableItem, cur_item)
if not a_BotMessage:
continue
if s_user_id == a_OwnerUserID:
continue
a_UserID = s_user_id
a_BotMessage = a_BotMessage.StaticCopy()
a_BotMessage.UpdateDesc(a_BotMessage.GetDesc().replace("#item_id", str(a_TableItem)))
inline_keyboard_func = None
if cur_item:
a_BotMessage.UpdateDesc(self.m_Table.ReplaceAllFieldTags(a_BotMessage.GetDesc(), cur_item))
inline_keyboard_func = self.GetShowItemInlineKeyboardTemplate(a_TableItem)
await self.SendMessageToUser(a_BotMessage, a_UserID, a_GetInlineButtonsFunc = inline_keyboard_func)
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
return bd_item_select.DBItemSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName)
def RegisterSelect(self, a_ButtonName, access_mode, only_parent = False): def RegisterSelect(self, a_ButtonName, access_mode, only_parent = False):
a_Prefix = None a_Prefix = None
if self.m_ParentModName: if self.m_ParentModName:
parent_mod = self.GetModule(self.m_ParentModName) parent_mod = self.GetModule(self.m_ParentModName)
a_Prefix = parent_mod.RegisterSelect(a_ButtonName, access_mode, only_parent = False) a_Prefix = parent_mod.RegisterSelect(a_ButtonName, access_mode, only_parent = False)
if not only_parent: if not only_parent:
a_Prefix = bd_item_select.SelectRegisterHandlers(self.m_Bot, \ a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(self.m_Bot, \
self.SelectSourceTemplate(a_Prefix, a_ButtonName), \ a_Prefix, \
self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID), \
self.m_Table.GetName(), \
self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY), \
self.m_GetButtonNameAndKeyValueAndAccessFunc, \ self.m_GetButtonNameAndKeyValueAndAccessFunc, \
self.GetMessage(Messages.SELECT), \ self.GetMessage(Messages.SELECT), \
self.m_GetAccessFunc,\ self.m_GetAccessFunc,\
access_mode = access_mode\ access_mode = access_mode\
) )
else:
return a_Prefix if not only_parent:
a_PrefixBase = a_ButtonName.GetDesc()
def AdditionalKeyboardForEditTemplate(self, a_Field, user_access = user_access.AccessMode.EDIT): a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(self.m_Bot, \
if a_Field.m_Type == bd_table.TableFieldType.ENUM: a_PrefixBase, \
def KeyboardButtons(a_Message, a_UserGroups): a_ButtonName, \
cur_buttons = [] self.m_Table.GetName(), \
for s in a_Field.m_Enum: self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY), \
cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EnumButton(s)), user_access, self.GetAccess()),] self.m_GetButtonNameAndKeyValueAndAccessFunc, \
return keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) self.GetMessage(Messages.SELECT), \
return KeyboardButtons self.m_GetAccessFunc,\
return None access_mode = access_mode\
def PostProccessingForFieldForEditTemplate(self, a_Field):
if a_Field.m_Type == bd_table.TableFieldType.ENUM:
def PostProccessing(a_Message):
for s in a_Field.m_Enum:
if a_Message == str(self.GetButton(EnumButton(s))):
return str(s)
return a_Message
return PostProccessing
return None
async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID):
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_EDIT
item_id = -1
await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID)
subscribe_type = bot_subscribes.SubscribeType.ITEM_EDIT
item_id = a_ItemID
await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID)
table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName()
cur_item = GetCurItem(self.m_Bot, table_name, key_name, a_ItemID)
#print(cur_item)
parent_id_field_index = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
if parent_id_field_index and cur_item and cur_item[parent_id_field_index]:
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT
item_id = cur_item[parent_id_field_index]
await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID)
def RegisterEdit(self, a_Field, a_AccessMode = user_access.AccessMode.EDIT):
a_ButtonName = self.GetButton(EditButton(a_Field.m_Destiny))
a_EditMessage = self.GetMessage(EditMessage(a_Field.m_Destiny))
a_FieldName = a_Field.m_Name
a_FieldType = bd_item.FieldType.text
if a_Field.m_Type == bd_table.TableFieldType.PHOTO:
a_FieldType = bd_item.FieldType.photo
if not a_ButtonName or not a_EditMessage:
return
async def OnChange(a_ItemID, a_ItemData, a_EditUserID):
await self.OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID)
return self.OnChange()
table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName()
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc
GetAccess = self.m_GetAccessFunc
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True)
a_Prefix = bd_item_edit.EditBDItemRegisterHandlers(self.m_Bot, \
self.SelectSourceTemplate(a_Prefix, a_ButtonName), \
MakeFSMForEdit(self.GetName(), a_FieldName), \
self.GetMessage(Messages.SELECT_TO_EDIT), \
self.ShowMessageTemplate(a_EditMessage), \
self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_EDIT)), \
table_name, \
key_name, \
a_FieldName, \
self.PostProccessingForFieldForEditTemplate(a_Field),\
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
self.AdditionalKeyboardForEditTemplate(a_Field),\
edit_keyboard_func, \
OnChange,\
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
self.m_EditPrefix.update({a_Field.m_Destiny: a_Prefix})
def GetAddFieldDestinys(self):
return (
bd_table.TableFieldDestiny.NAME,
bd_table.TableFieldDestiny.DESC,
bd_table.TableFieldDestiny.PHOTO,
bd_table.TableFieldDestiny.SUBSCRIBE_TYPE,
bd_table.TableFieldDestiny.ITEM_ID,
bd_table.TableFieldDestiny.USER_NAME,
bd_table.TableFieldDestiny.USER_FAMILY_NAME,
bd_table.TableFieldDestiny.USER_MIDDLE_NAME,
bd_table.TableFieldDestiny.USER_BIRTHDAY,
bd_table.TableFieldDestiny.USER_ADDRESS,
bd_table.TableFieldDestiny.USER_CONTACTS,
bd_table.TableFieldDestiny.USER_CONFIRM,
) )
return a_Prefix
def GetAddFields(self):
add_destiny = self.GetAddFieldDestinys()
fields = []
for f in self.m_Table.GetFields():
if f.m_Destiny in add_destiny:
fields += [f]
return fields
def AddBDItemRegisterHandlers(self, a_StartCheckFunc, a_AddBDItemFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD):
fields = self.GetAddFields()
if len(fields) == 0:
return
fsm = MakeFSMForAdd(self.GetName(), fields)
keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(self.m_Bot, a_AccessFunc, access_mode)
keyboard_skip_and_cancel = bd_item.GetSkipAndCancelKeyboardButtonsTemplate(self.m_Bot, a_AccessFunc, access_mode)
reg_func = self.m_Bot.RegisterMessageHandler
if a_ParentTableName:
reg_func = self.m_Bot.RegisterCallbackHandler
def GetFieldType(a_Field):
if a_Field.m_Type == bd_table.TableFieldType.PHOTO:
return bd_item.FieldType.photo
return bd_item.FieldType.text
def GetContentTypes(a_Field):
if a_Field.m_Type == bd_table.TableFieldType.PHOTO:
return ['photo', 'text']
return ['text']
def GetKeyboard(a_Field):
if a_Field.m_Type == bd_table.TableFieldType.PHOTO:
return keyboard_skip_and_cancel
return keyboard_cancel
f_id = 0
f = fields[f_id]
keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(f, user_access.AccessMode.ADD), GetKeyboard(f))
reg_func(bd_item_add.StartAddBDItemTemplate(self.m_Bot, fsm, getattr(fsm, f'item{f_id}'), self.ShowMessageTemplate(self.GetMessage(CreateMessage(f.m_Destiny))), a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard, a_ButtonFunc, access_mode), a_StartCheckFunc)
for i in range(len(fields) - 1):
f = fields[i]
next_f = fields[i + 1]
keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(next_f, user_access.AccessMode.ADD), GetKeyboard(next_f))
self.m_Bot.RegisterMessageHandler(bd_item_add.NextAddBDItemTemplate(self.m_Bot, fsm, None, a_ParentTableName, a_ParentKeyFieldName, f.m_Name, self.ShowMessageTemplate(self.GetMessage(CreateMessage(next_f.m_Destiny))), None, a_AccessFunc, keyboard, a_ButtonFunc, access_mode, field_type = GetFieldType(f)), content_types = GetContentTypes(f), state = getattr(fsm, f'item{i}'))
f_id = len(fields) - 1
f = fields[f_id]
self.m_Bot.RegisterMessageHandler(bd_item_add.FinishAddBDItemTemplate(self.m_Bot, fsm, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, f.m_Name, self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_CREATE)), None, a_AccessFunc, a_ButtonFunc, access_mode, field_type = GetFieldType(f)), content_types = GetContentTypes(f), state = getattr(fsm, f'item{f_id}'))
def GetKeyFieldDestiny(self):
return bd_table.TableFieldDestiny.KEY
def GetKeyFieldName(self):
return self.m_Table.GetFieldNameByDestiny(self.GetKeyFieldDestiny())
def GetKeyFieldID(self):
return self.m_Table.GetFieldIDByDestiny(self.GetKeyFieldDestiny())
def RegisterHandlers(self): def RegisterHandlers(self):
super().RegisterHandlers() super().RegisterHandlers()
table_name = self.m_Table.GetName() table_name = self.m_Table.GetName()
key_name = self.GetKeyFieldName() key_name = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME) name_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.NAME)
desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC) desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC)
photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO) photo_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PHOTO)
@ -629,7 +245,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
if self.m_ParentModName: if self.m_ParentModName:
parent_mod = self.GetModule(self.m_ParentModName) parent_mod = self.GetModule(self.m_ParentModName)
parent_table_name = parent_mod.m_Table.GetName() parent_table_name = parent_mod.m_Table.GetName()
parent_key_name = parent_mod.GetKeyFieldName() parent_key_name = parent_mod.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
def GetViewItemInlineKeyboardTemplate(a_ItemID): def GetViewItemInlineKeyboardTemplate(a_ItemID):
return self.GetViewItemInlineKeyboardTemplate(a_ItemID) return self.GetViewItemInlineKeyboardTemplate(a_ItemID)
@ -643,31 +259,36 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
a_ButtonName = self.GetButton(ButtonNames.LIST) a_ButtonName = self.GetButton(ButtonNames.LIST)
if a_ButtonName: if a_ButtonName:
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True)
self.m_SelectPrefix = a_Prefix if a_Prefix:
a_Prefix = bd_item_select.SelectRegisterHandlers(self.m_Bot,\ bd_item_view.LastSelectAndShowBDItemRegisterHandlers(self.m_Bot, \
self.SelectSourceTemplate(a_Prefix, a_ButtonName), \
GetButtonNameAndKeyValueAndAccess,\
self.GetMessage(Messages.SELECT),\
GetAccess,\
access_mode = user_access.AccessMode.VIEW\
)
self.m_ShowPrefix = a_Prefix
bd_item_view.ShowBDItemRegisterHandlers(self.m_Bot,\
a_Prefix,\ a_Prefix,\
parent_id_field, \
table_name,\ table_name,\
key_name,\ key_name, \
self.ShowMessageTemplate(self.GetMessage(Messages.OPEN), GetViewItemInlineKeyboardTemplate, a_EnablePhoto = True),\ self.ShowMessageTemplate(self.GetMessage(Messages.OPEN), GetViewItemInlineKeyboardTemplate), \
GetAccess,\ GetButtonNameAndKeyValueAndAccess, \
defaul_keyboard_func,\ self.GetMessage(Messages.SELECT), \
GetAccess, \
defaul_keyboard_func, \
access_mode = user_access.AccessMode.VIEW\ access_mode = user_access.AccessMode.VIEW\
) )
else:
bd_item_view.FirstSelectAndShowBDItemRegisterHandlers(self.m_Bot, \
a_ButtonName, \
table_name, \
key_name, \
self.ShowMessageTemplate(self.GetMessage(Messages.OPEN), GetViewItemInlineKeyboardTemplate), \
GetButtonNameAndKeyValueAndAccess, \
self.GetMessage(Messages.SELECT), \
GetAccess, \
defaul_keyboard_func\
)
self.m_SelectPrefix = a_Prefix
# Удаление # Удаление
a_ButtonName = self.GetButton(ButtonNames.DEL) a_ButtonName = self.GetButton(ButtonNames.DEL)
if a_ButtonName: if a_ButtonName:
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW) a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.DELETE)
self.m_DelPrefix = a_Prefix
bd_item_delete.DeleteBDItemRegisterHandlers(self.m_Bot, \ bd_item_delete.DeleteBDItemRegisterHandlers(self.m_Bot, \
a_Prefix, \ a_Prefix, \
table_name, \ table_name, \
@ -681,19 +302,29 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
# Добавление # Добавление
a_ButtonName = self.GetButton(ButtonNames.ADD) a_ButtonName = self.GetButton(ButtonNames.ADD)
if a_ButtonName: if a_ButtonName:
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.ADD, only_parent = True)
self.m_AddPrefix = a_Prefix
check_func = bd_item.GetCheckForTextFunc(a_ButtonName) check_func = bd_item.GetCheckForTextFunc(a_ButtonName)
if a_Prefix: if a_Prefix:
check_func = bd_item.GetCheckForPrefixFunc(a_Prefix) check_func = bd_item.GetCheckForPrefixFunc(a_Prefix)
self.AddBDItemRegisterHandlers(\ bd_item_add.AddBDItem3RegisterHandlers(self.m_Bot, \
check_func, \ check_func, \
self.GetFSM(FSMs.CREATE), \
self.GetFSM(FSMs.CREATE).name,\
self.GetFSM(FSMs.CREATE).desc, \
self.GetFSM(FSMs.CREATE).photo,\
self.m_AddBDItemFunc, \ self.m_AddBDItemFunc, \
self.ShowMessageTemplate(self.GetMessage(Messages.CREATE_NAME)), \
self.ShowMessageTemplate(self.GetMessage(Messages.CREATE_DESC)), \
self.ShowMessageTemplate(self.GetMessage(Messages.CREATE_PHOTO)), \
self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_CREATE)), \
a_Prefix,\ a_Prefix,\
parent_table_name, \ parent_table_name, \
parent_key_name, \ parent_key_name, \
name_field, \
desc_field, \
photo_field, \
GetButtonNameAndKeyValueAndAccess, \ GetButtonNameAndKeyValueAndAccess, \
GetAccess, \ GetAccess, \
self.m_GetStartKeyboardButtonsFunc\ self.m_GetStartKeyboardButtonsFunc\
@ -701,6 +332,37 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
# Редактирование # Редактирование
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc
def RegisterEdit(a_ButtonName, a_FSM, a_EditMessage, a_FieldName, a_FieldType, a_AccessMode = user_access.AccessMode.EDIT):
if not a_ButtonName:
return
def OnChange():
return self.OnChange()
a_Prefix = self.RegisterSelect(a_ButtonName, a_AccessMode, only_parent = True)
check_func = bd_item.GetCheckForTextFunc(a_ButtonName)
if a_Prefix:
check_func = bd_item.GetCheckForPrefixFunc(a_Prefix)
#print(a_ButtonName, a_Prefix, check_func)
bd_item_edit.EditBDItemRegisterHandlers(self.m_Bot, \
a_Prefix, \
a_FSM, \
check_func, \
self.GetMessage(Messages.SELECT_TO_EDIT), \
self.ShowMessageTemplate(a_EditMessage), \
self.ShowMessageTemplate(self.GetMessage(Messages.SUCCESS_EDIT)), \
table_name, \
key_name, \
parent_id_field, \
a_FieldName, \
GetButtonNameAndKeyValueAndAccess, \
GetAccess, \
edit_keyboard_func, \
OnChange,\
access_mode = a_AccessMode, \
field_type = a_FieldType\
)
a_ButtonName = self.GetButton(ButtonNames.EDIT) a_ButtonName = self.GetButton(ButtonNames.EDIT)
if a_ButtonName: if a_ButtonName:
self.m_Bot.RegisterMessageHandler(\ self.m_Bot.RegisterMessageHandler(\
@ -714,8 +376,11 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
bd_item.GetCheckForTextFunc(a_ButtonName)\ bd_item.GetCheckForTextFunc(a_ButtonName)\
) )
for f in self.m_Table.GetFields(): RegisterEdit(self.GetButton(ButtonNames.EDIT_NAME), self.GetFSM(FSMs.EDIT_NAME), self.GetMessage(Messages.EDIT_NAME), name_field, bd_item.FieldType.text)
self.RegisterEdit(f) RegisterEdit(self.GetButton(ButtonNames.EDIT_DESC), self.GetFSM(FSMs.EDIT_DESC), self.GetMessage(Messages.EDIT_DESC), desc_field, bd_item.FieldType.text)
RegisterEdit(self.GetButton(ButtonNames.EDIT_PHOTO), self.GetFSM(FSMs.EDIT_PHOTO), self.GetMessage(Messages.EDIT_PHOTO), photo_field, bd_item.FieldType.photo)
RegisterEdit(self.GetButton(ButtonNames.EDIT_ACCESS), self.GetFSM(FSMs.EDIT_ACCESS), self.GetMessage(Messages.EDIT_ACCESS), access_field, bd_item.FieldType.text)
RegisterEdit(self.GetButton(ButtonNames.EDIT_DEFAULT_ACCESS), self.GetFSM(FSMs.EDIT_DEFAULT_ACCESS), self.GetMessage(Messages.EDIT_DEFAULT_ACCESS), def_access_field, bd_item.FieldType.text)
def OnChange(self): def OnChange(self):
pass pass

70
bot_modules/needs.py

@ -3,9 +3,28 @@
# Потребности # Потребности
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message from bot_modules import mod_table_operate, mod_simple_message
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateNeed(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditNeedPhotoItem(StatesGroup):
item_field = State()
class FSMEditNeedNameItem(StatesGroup):
item_field = State()
class FSMEditNeedDescItem(StatesGroup):
item_field = State()
class FSMEditNeedAccessItem(StatesGroup):
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'needs' module_name = 'needs'
@ -23,7 +42,7 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR), bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT), bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
@ -31,6 +50,14 @@ table = bd_table.Table(table_name, [
init_access = f'{user_access.user_access_group_new}=va' init_access = f'{user_access.user_access_group_new}=va'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateNeed,
mod_table_operate.FSMs.EDIT_NAME: FSMEditNeedNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditNeedDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditNeedPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditNeedAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -39,10 +66,10 @@ button_names = {
mod_table_operate.ButtonNames.LIST: "📃 Список потребностей", mod_table_operate.ButtonNames.LIST: "📃 Список потребностей",
mod_table_operate.ButtonNames.ADD: "☑ Добавить потребность", mod_table_operate.ButtonNames.ADD: "☑ Добавить потребность",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать потребность", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать потребность",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение у потребности", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у потребности",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название у потребности", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у потребности",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание у потребности", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание у потребности",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к потребности", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к потребности",
mod_table_operate.ButtonNames.DEL: "❌ Удалить потребность", mod_table_operate.ButtonNames.DEL: "❌ Удалить потребность",
} }
@ -64,17 +91,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' mod_table_operate.Messages.CREATE_NAME: '''
Создание потребности. Шаг 1 Создание потребности. Шаг 1
Введите название потребности: Введите название потребности:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание потребности. Шаг 2 Создание потребности. Шаг 2
Введите описание потребности: Введите описание потребности:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание потребности. Шаг 3 Создание потребности. Шаг 3
Загрузите обложку для потребности (Фото): Загрузите обложку для потребности (Фото):
@ -87,23 +114,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите потребность, которую вы хотите отредактировать. Выберите потребность, которую вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для потребности (Фото): Загрузите новую обложку для потребности (Фото):
Она будет отображаться в её описании. Она будет отображаться в её описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название потребности: Текущее название потребности:
#{name_field} #{name_field}
Введите новое название потребности: Введите новое название потребности:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание потребности: Текущее описание потребности:
#{desc_field} #{desc_field}
Введите новое описание потребности: Введите новое описание потребности:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к потребности: Текущий доступ к потребности:
#{access_field} #{access_field}
@ -119,22 +146,9 @@ messages = {
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Потребность успешно удалёна!''', mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Потребность успешно удалёна!''',
} }
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Потребность создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Потребность отредактирована''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Потребность удалёна''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Потребность отредактирована #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Потребность удалёна #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Потребность создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Потребность отредактирована''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Потребность удалёна''',
}
messages.update(messages_subscribes)
class ModuleNeeds(mod_table_operate.TableOperateModule): class ModuleNeeds(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

336
bot_modules/orders.py

@ -1,336 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Заказы
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes
from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_select, bd_item_view, bd_item
from enum import Enum
from enum import auto
class OrderStatus(Enum):
NEW = auto()
PAY = auto()
ADDRESS = auto()
FINISH = auto()
# ---------------------------------------------------------
# БД
module_name = 'orders'
table_name = module_name
key_name = 'orderID'
user_id_field = 'userID'
name_field = 'orderName'
desc_field = 'orderDesc'
photo_field = 'orderPhoto'
photo_pay_field = 'orderPhotoPay'
status_field = 'orderStatus'
address_field = 'orderAddress'
access_field = 'orderAccess'
create_datetime_field = 'orderCreateDateTime'
parent_id_field = 'catID'
pay_field = bd_table.TableField(photo_pay_field, bd_table.TableFieldDestiny.PHOTO_PAY, bd_table.TableFieldType.PHOTO)
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(user_id_field, bd_table.TableFieldDestiny.USER_ID, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO),
pay_field,
bd_table.TableField(status_field, bd_table.TableFieldDestiny.STATUS, bd_table.TableFieldType.ENUM, a_Enum = OrderStatus),
bd_table.TableField(address_field, bd_table.TableFieldDestiny.ADDRESS, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
])
init_access = f'{user_access.user_access_group_auth_users}=vea'
# ---------------------------------------------------------
# Сообщения и кнопки
class ButtonNames(Enum):
LIST_ALL = auto()
button_names = {
mod_simple_message.ButtonNames.START: "🛒 Заказы",
mod_table_operate.ButtonNames.SHOW: "☐ Открыть заказ",
mod_table_operate.ButtonNames.LIST: "📃 Список моих текущих заказов",
ButtonNames.LIST_ALL: "📃 Список всех моих заказов",
mod_table_operate.ButtonNames.ADD: "✅ Добавить заказ",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать мой заказ",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): "🧾 Загрузить чек по оплате моего заказа",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в моём заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в моём заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в моём заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ADDRESS): "𝌴 Изменить адрес в моём заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к моему заказу",
mod_table_operate.ButtonNames.DEL: "❌ Удалить мой заказ",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите заказ:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, заказ не найден
''',
mod_table_operate.Messages.OPEN: f'''
<b>Номер заказа: #{key_name} </b>
<b>Имя заказа: #{name_field}</b>
<b>Описание и состав заказа:</b> #{desc_field}
<b>Статус:</b> #{status_field}
<b>Адрес доставки:</b> #{address_field}
<b>Время создания:</b> #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): '''
Создание заказа. Шаг 1
Введите название заказа:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): '''
Создание заказа. Шаг 2
Введите описание заказа:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): '''
Создание заказа. Шаг 3
Загрузите фотографию для заказа. Фото будет отображаться в его описании.
(Если фотографии нет, то нажмите "⏩ Пропустить")
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Заказ успешно добавлен!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите заказ, который вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO_PAY): '''
Загрузите чек по оплате заказа (фото):
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): '''
Загрузите новую обложку для заказа (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f'''
Текущее название заказа:
#{name_field}
Введите новое название заказа:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f'''
Текущее описание заказа:
<code>#{desc_field}</code>
Введите новое описание заказа:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ADDRESS): f'''
Текущий адрес заказа:
#{address_field}
Введите новый адрес доставки заказа (укажите, кто, когда и где его сможет забрать):
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к заказу:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Заказ успешно отредактирован!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите заказ, который вы хотите удалить.
Все задачи и потребности в этом заказе так же будут удалены!
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Заказ успешно удалён!''',
}
messages_order_status = {
mod_table_operate.EnumMessageForView(OrderStatus.NEW): f'''Заказ создан, ожидает модерации''',
mod_table_operate.EnumMessageForView(OrderStatus.PAY): f'''Заказ ожидает оплаты''',
mod_table_operate.EnumMessageForView(OrderStatus.ADDRESS): f'''Заказ ожидает указания адреса доставки''',
mod_table_operate.EnumMessageForView(OrderStatus.FINISH): f'''Заказ выполнен''',
}
messages.update(messages_order_status)
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Заказ создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Заказ отредактирован''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Заказ удалён''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Заказ отредактирован #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Заказ удалён #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Заказ создан
<b>Номер заказа: #{key_name} </b>
<b>Имя заказа: #{name_field}</b>
<b>Описание и состав заказа:</b> #{desc_field}''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Заказ отредактирован
<b>Номер заказа: #{key_name} </b>
<b>Имя заказа: #{name_field}</b>
<b>Описание и состав заказа:</b> #{desc_field}''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Заказ удалён''',
}
messages.update(messages_subscribes)
def GetCurItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_ParentIDFieldName, a_StatusFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID):
user_id = str(a_Message.from_user.id)
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_UserIDFieldName} = ? AND {a_StatusFieldName} != ?'
return a_Bot.SQLRequest(request, param = ([a_ParentID, user_id, str(OrderStatus.FINISH)]))
return GetBDItems
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_ParentIDFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID):
user_id = str(a_Message.from_user.id)
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_UserIDFieldName} = ?'
print('GetBDItemsForUserTemplate', user_id, request, a_ParentID)
return a_Bot.SQLRequest(request, param = ([a_ParentID, user_id]))
return GetBDItems
class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
def __init__(self, a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName, a_OnlyCurrent = False):
super().__init__(a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName)
self.m_OnlyCurrent = a_OnlyCurrent
def GetItemsFunc(self):
if self.m_OnlyCurrent:
return GetCurItemsTemplate(self.m_Bot, self.m_TableName, user_id_field, self.m_ParentIDFieldName, status_field)
return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, user_id_field, self.m_ParentIDFieldName)
class ModuleOrders(mod_table_operate.TableOperateModule):
def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName, a_OnlyCurrent = True)
def SelectSourceForAllTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName)
def AddBDItemFunc(self, a_ItemData, a_UserID):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
a_ItemData[name_field] = ''
a_ItemData[photo_field] = ''
a_ItemData[user_id_field] = a_UserID
a_ItemData[status_field] = str(OrderStatus.NEW)
a_ItemData[address_field] = ''
a_ItemData[photo_pay_field] = '0'
return super().AddBDItemFunc(a_ItemData, a_UserID)
def GetModuleButtons(self):
buttons = super().GetModuleButtons();
add_order_button = [
keyboard.ButtonWithAccess(self.GetButton(mod_table_operate.ButtonNames.ADD), user_access.AccessMode.ADD, self.GetAccess()),
]
return add_order_button + buttons
def GetNameFromDesc(self, a_Desc):
name = ''
lines = str(a_Desc).splitlines()
for l in lines:
name = l.strip();
if len(name) > 0:
break;
return name[0:16]
def GetButtonNameAndKeyValueAndAccess(self, a_Item):
user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID)
key_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)
desc_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.DESC)
n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item)
return str(a_Item[key_field_id]) + ":" + str(self.GetNameFromDesc(a_Item[desc_field_id])), k, a
def GetAddFieldDestinys(self):
return (
bd_table.TableFieldDestiny.DESC,
)
def GetStartButtons(self, a_Message, a_UserGroups):
pay_access = self.GetAccessForEditKeyboardButtons(pay_field)
return [
[mod_table_operate.ButtonNames.ADD, user_access.AccessMode.ADD],
[mod_table_operate.EditButton(pay_field.m_Destiny), pay_access],
[mod_table_operate.ButtonNames.EDIT, user_access.AccessMode.EDIT],
[mod_table_operate.ButtonNames.LIST, user_access.AccessMode.VIEW],
[mod_table_operate.ButtonNames.DEL, user_access.AccessMode.DELETE],
]
def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
parent_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
cur_buttons = [
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.LIST_ALL), user_access.AccessMode.VIEW, self.GetAccess()),
]
return parent_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
def RegisterHandlers(self):
super().RegisterHandlers()
table_name = self.m_Table.GetName()
key_name = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
def GetViewItemInlineKeyboardTemplate(a_ItemID):
return self.GetViewItemInlineKeyboardTemplate(a_ItemID)
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc
GetAccess = self.m_GetAccessFunc
default_keyboard_func = self.m_GetStartKeyboardButtonsFunc
# Список всех заказов
a_ButtonName = self.GetButton(ButtonNames.LIST_ALL)
if a_ButtonName:
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True)
a_Prefix = bd_item_select.SelectRegisterHandlers(self.m_Bot,\
self.SelectSourceForAllTemplate(a_Prefix, a_ButtonName), \
GetButtonNameAndKeyValueAndAccess,\
self.GetMessage(mod_table_operate.Messages.SELECT),\
GetAccess,\
access_mode = user_access.AccessMode.VIEW\
)
bd_item_view.ShowBDItemRegisterHandlers(self.m_Bot,\
a_Prefix,\
table_name,\
key_name,\
self.ShowMessageTemplate(self.GetMessage(mod_table_operate.Messages.OPEN),GetViewItemInlineKeyboardTemplate, a_EnablePhoto = True),\
GetAccess,\
default_keyboard_func,\
access_mode = user_access.AccessMode.VIEW\
)
class ModuleUserOrders(ModuleOrders):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name
def GetShowItemInlineKeyboard(self, a_Message, a_UserGroups, a_ItemID):
all_orders_mod = self.GetModule('all_orders')
if not all_orders_mod:
return None
cur_buttons = [
keyboard.InlineButtonWithAccess(all_orders_mod.GetButton(mod_table_operate.ButtonNames.SHOW), all_orders_mod.GetShowPrefix(), a_ItemID, all_orders_mod.GetAccess(), user_access.AccessMode.VIEW),
]
return keyboard.MakeInlineKeyboardButtons(self.m_Bot, cur_buttons, a_UserGroups)

138
bot_modules/orders_cat.py

@ -1,138 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Категории для заказов
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes
from bot_modules import mod_table_operate, mod_simple_message
# ---------------------------------------------------------
# БД
module_name = 'orders_cat'
table_name = module_name
key_name = 'catID'
name_field = 'catName'
desc_field = 'catDesc'
photo_field = 'catPhoto'
access_field = 'catAccess'
create_datetime_field = 'catCreateDateTime'
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
])
init_access = f'{user_access.user_access_group_new}=v'
# ---------------------------------------------------------
# Сообщения и кнопки
button_names = {
mod_simple_message.ButtonNames.START: "🟥 Категории",
mod_table_operate.ButtonNames.LIST: "📃 Список категорий",
mod_table_operate.ButtonNames.ADD: "✅ Добавить категорию",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать категорию",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в категории",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в категории",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в категории",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к категории",
mod_table_operate.ButtonNames.DEL: "❌ Удалить категорию",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите категорию:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, категория не найдена
''',
mod_table_operate.Messages.OPEN: f'''
<b>Категория: #{name_field}</b>
#{desc_field}
Время создания: #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): '''
Создание категории. Шаг 1
Введите название категории:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): '''
Создание категории. Шаг 2
Введите описание категории:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): '''
Создание категории. Шаг 3
Загрузите обложку для категории (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Категория успешно добавлена!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите проект, который вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): '''
Загрузите новую обложку для категории (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f'''
Текущее название категории:
#{name_field}
Введите новое название категории:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f'''
Текущее описание категории:
#{desc_field}
Введите новое описание категории:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к категории:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Категория успешно отредактирована!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите категорию, которую вы хотите удалить.
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Категория успешно удалёна!''',
}
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Категория создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Категория отредактирована''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Категория удалена''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Категория отредактирована #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Категория удалена #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Категория создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Категория отредактирована''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Категория удалена''',
}
messages.update(messages_subscribes)
class ModuleOrdersCat(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name

71
bot_modules/profile.py

@ -4,13 +4,34 @@
# Профиль пользователя # Профиль пользователя
from bot_sys import user_access, bot_bd, bd_table from bot_sys import user_access, bot_bd, bd_table
from bot_modules import mod_simple_message, access, access_utils, groups_utils, users from bot_modules import mod_simple_message, groups, access, access_utils, groups_utils
from template import bd_item, simple_message from template import bd_item, simple_message
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'profile' module_name = 'profile'
table_name = 'users'
key_name = 'user_id'
name_field = 'userName'
name1_field = 'userFirstName'
name2_field = 'userLastName'
is_bot_field = 'userIsBot'
language_code_field = 'userLanguageCode'
access_field = 'userAccess'
create_datetime_field = 'createDateTime'
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(name1_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(name2_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(is_bot_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(language_code_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
])
button_names = { button_names = {
mod_simple_message.ButtonNames.START: "📰 Профиль", mod_simple_message.ButtonNames.START: "📰 Профиль",
} }
@ -19,33 +40,59 @@ messages = {
mod_simple_message.Messages.START: f''' mod_simple_message.Messages.START: f'''
<b>📰 Профиль:</b> <b>📰 Профиль:</b>
<b>ID:</b> #{users.key_name} <b>ID:</b> #{key_name}
<b>Имя:</b> #{users.name_field} <b>Имя:</b> #{name_field}
<b>Имя1:</b> #{users.name1_field} <b>Имя1:</b> #{name1_field}
<b>Имя2:</b> #{users.name2_field} <b>Имя2:</b> #{name2_field}
<b>Код языка:</b> #{users.language_code_field} <b>Код языка:</b> #{language_code_field}
<b>Дата добавления:</b> #{users.create_datetime_field} <b>Дата добавления:</b> #{create_datetime_field}
''', ''',
} }
init_access = f'{user_access.user_access_group_new}=+' init_access = f'{user_access.user_access_group_new}=+'
class ModuleProfile(mod_simple_message.SimpleMessageModule): class ModuleProfile(mod_simple_message.SimpleMessageModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(messages, button_names, init_access, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetInitBDCommands(self):
return super(). GetInitBDCommands() + [
table.GetInitTableRequest(),
]
def GetName(self): def GetName(self):
return module_name return module_name
# Основной обработчик главного сообщения # Основной обработчик главного сообщения
async def StartMessageHandler(self, a_Message, state = None): async def StartMessageHandler(self, a_Message, state = None):
user_info = users.GetUserInfo(self.m_Bot, a_Message.from_user.id) user_info = GetUserInfo(self.m_Bot, a_Message.from_user.id)
lang = str(a_Message.from_user.language_code) lang = str(a_Message.from_user.language_code)
if not user_info is None: if not user_info is None:
msg = self.GetMessage(mod_simple_message.Messages.START) msg = self.GetMessage(mod_simple_message.Messages.START)
msg = msg.GetMessageForLang(lang).StaticCopy() msg = msg.GetMessageForLang(lang).StaticCopy()
msg.UpdateDesc(users.table.ReplaceAllFieldTags(msg.GetDesc(), user_info)) msg.UpdateDesc(table.ReplaceAllFieldTags(msg.GetDesc(), user_info))
return simple_message.WorkFuncResult(msg, item_access = str(user_info[users.table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)])) return simple_message.WorkFuncResult(msg, item_access = str(user_info[table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)]))
return await super().StartMessageHandler(a_Message, state) return await super().StartMessageHandler(a_Message, state)
# Работа с базой данных пользователей
# Добавление пользователя, если он уже есть, то игнорируем
def AddUser(a_Bot, a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode):
a_Bot.SQLRequest(f"INSERT OR IGNORE INTO users ({key_name}, {name_field}, {name1_field}, {name2_field}, {is_bot_field}, {language_code_field}, {access_field}, {create_datetime_field}) VALUES (?, ?, ?, ?, ?, ?, ?, {bot_bd.GetBDDateTimeNow()});",
commit=True, param = (a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode, access_utils.GetItemDefaultAccessForModule(a_Bot, module_name)))
user_groups = groups_utils.GetUserGroupData(a_Bot, a_UserID)
# Если пользователь не состоит ни в одной группе, то добавляем его в группу user_access.user_access_group_new
if len(user_groups.group_names_list) == 0:
new_group_id = a_Bot.SQLRequest(f'SELECT {groups.key_table_groups_name} FROM {groups.table_groups_name} WHERE {groups.name_table_groups_field} = ?',
param = [user_access.user_access_group_new])
if new_group_id and new_group_id[0]:
a_Bot.SQLRequest(f"INSERT OR IGNORE INTO {groups.table_user_in_groups_name} ({groups.user_id_field}, {groups.key_table_groups_name}, {groups.access_field}, {groups.create_datetime_field}) VALUES (?, ?, ?, {bot_bd.GetBDDateTimeNow()});",
commit=True, param = (a_UserID, new_group_id[0][0], access_utils.GetItemDefaultAccessForModule(a_Bot, module_name)))
def GetUserInfo(a_Bot, a_UserID):
user_info = a_Bot.SQLRequest('SELECT * FROM users WHERE user_id = ?', param = [a_UserID])
if len(user_info) != 0:
return user_info[0]
return None

76
bot_modules/projects.py

@ -3,9 +3,28 @@
# Проекты # Проекты
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message from bot_modules import mod_table_operate, mod_simple_message
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateProject(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditProjectPhotoItem(StatesGroup):
item_field = State()
class FSMEditProjectNameItem(StatesGroup):
item_field = State()
class FSMEditProjectDescItem(StatesGroup):
item_field = State()
class FSMEditProjectAccessItem(StatesGroup):
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'projects' module_name = 'projects'
@ -22,13 +41,21 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR), bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
]) ])
init_access = f'{user_access.user_access_group_new}=va' init_access = f'{user_access.user_access_group_new}=va'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateProject,
mod_table_operate.FSMs.EDIT_NAME: FSMEditProjectNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditProjectDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditProjectPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditProjectAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -37,10 +64,10 @@ button_names = {
mod_table_operate.ButtonNames.LIST: "📃 Список проектов", mod_table_operate.ButtonNames.LIST: "📃 Список проектов",
mod_table_operate.ButtonNames.ADD: "✅ Добавить проект", mod_table_operate.ButtonNames.ADD: "✅ Добавить проект",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать проект", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать проект",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в проекте", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение в проекте",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в проекте", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название в проекте",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в проекте", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание в проекте",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к проекту", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к проекту",
mod_table_operate.ButtonNames.DEL: "❌ Удалить проект", mod_table_operate.ButtonNames.DEL: "❌ Удалить проект",
} }
@ -62,17 +89,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' mod_table_operate.Messages.CREATE_NAME: '''
Создание проекта. Шаг 1 Создание проекта. Шаг 1
Введите название проекта: Введите название проекта:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание проекта. Шаг 2 Создание проекта. Шаг 2
Введите описание проекта: Введите описание проекта:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание проекта. Шаг 3 Создание проекта. Шаг 3
Загрузите обложку для проекта (Фото): Загрузите обложку для проекта (Фото):
@ -85,23 +112,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите проект, который вы хотите отредактировать. Выберите проект, который вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для проекта (Фото): Загрузите новую обложку для проекта (Фото):
Она будет отображаться в его описании. Она будет отображаться в его описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название проекта: Текущее название проекта:
#{name_field} #{name_field}
Введите новое название проекта: Введите новое название проекта:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание проекта: Текущее описание проекта:
#{desc_field} #{desc_field}
Введите новое описание проекта: Введите новое описание проекта:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к проекту: Текущий доступ к проекту:
#{access_field} #{access_field}
@ -117,23 +144,16 @@ messages = {
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Проект успешно удалён!''', mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Проект успешно удалён!''',
} }
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Проект создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Проект отредактирован''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Проект удалён''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Проект отредактирован #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Проект удалён #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Проект создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Проект отредактирован''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Проект удалён''',
}
messages.update(messages_subscribes)
class ModuleProjects(mod_table_operate.TableOperateModule): class ModuleProjects(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name
def GetModuleButtons(self):
return super().GetModuleButtons() + [
keyboard.ButtonWithAccess(self.GetButton(mod_table_operate.ButtonNames.LIST), user_access.AccessMode.VIEW, self.GetAccess()),
]

8
bot_modules/start.py

@ -4,7 +4,7 @@
# Стартовое меню # Стартовое меню
from bot_sys import user_access from bot_sys import user_access
from bot_modules import mod_simple_message, users from bot_modules import mod_simple_message, profile
from template import bd_item from template import bd_item
module_name = 'start' module_name = 'start'
@ -23,8 +23,8 @@ messages = {
init_access = f'{user_access.user_access_group_all}=+' init_access = f'{user_access.user_access_group_all}=+'
class ModuleStart(mod_simple_message.SimpleMessageModule): class ModuleStart(mod_simple_message.SimpleMessageModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(messages, button_names, init_access, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name
@ -37,7 +37,7 @@ class ModuleStart(mod_simple_message.SimpleMessageModule):
last_name = str(a_Message.from_user.last_name) last_name = str(a_Message.from_user.last_name)
is_bot = str(a_Message.from_user.is_bot) is_bot = str(a_Message.from_user.is_bot)
language_code = str(a_Message.from_user.language_code) language_code = str(a_Message.from_user.language_code)
users.AddUser(self.m_Bot, user_id, user_name, first_name, last_name, is_bot, language_code) profile.AddUser(self.m_Bot, user_id, user_name, first_name, last_name, is_bot, language_code)
self.m_Log.Info(f'Пользователь {user_id} {user_name} авторизовался в боте. Полные данные {a_Message.from_user}.') self.m_Log.Info(f'Пользователь {user_id} {user_name} авторизовался в боте. Полные данные {a_Message.from_user}.')
return await super().StartMessageHandler(a_Message, state) return await super().StartMessageHandler(a_Message, state)

246
bot_modules/subscribes.py

@ -1,246 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Подписки
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes
from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_select, bd_item_view, bd_item
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from enum import Enum
from enum import auto
class FSMAddSubsType(StatesGroup):
bd_item = State()
# ---------------------------------------------------------
# БД
module_name = 'subscribes'
table_name = module_name
key_field = 'subsKey'
mod_name_field = 'modName'
type_field = 'subsType'
item_id_field = 'itemID'
access_field = 'subsAccess'
create_datetime_field = 'subsCreateDateTime'
parent_id_field = 'userID'
table_mod_name_field = bd_table.TableField(mod_name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR)
table_type_field = bd_table.TableField(type_field, bd_table.TableFieldDestiny.SUBSCRIBE_TYPE, bd_table.TableFieldType.ENUM, a_Enum = bot_subscribes.SubscribeType)
table_item_id_field = bd_table.TableField(item_id_field, bd_table.TableFieldDestiny.ITEM_ID, bd_table.TableFieldType.STR)
table_user_id_field = bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.STR)
table = bd_table.Table(table_name, [
bd_table.TableField(key_field, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
table_mod_name_field,
table_type_field,
table_item_id_field,
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
table_user_id_field,
],
[
[table_mod_name_field, table_type_field, table_user_id_field, table_item_id_field],
]
)
init_access = f'{user_access.user_access_group_new}=-'
button_names = {
mod_simple_message.ButtonNames.START: "⚡ Подписки",
mod_table_operate.ButtonNames.LIST: "📃 Список моих текущих подписок",
mod_table_operate.ButtonNames.ADD: "✅ Добавить подписку",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать мою подписку",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить модуль в моей подписке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.SUBSCRIBE_TYPE): "𝌴 Изменить тип в моей подписке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ITEM_ID): "𝌴 Изменить элемент в моей подписке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к моей подписке",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_ADD): "Добавление элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_DEL): "Удаление какого либо элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_EDIT): "Редактирование какого либо элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ITEM_DEL): "Удаление определённого элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ITEM_EDIT): "Редактирование определённого элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT): "Добавление элемента с родителем",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT): "Удаление элемента с родителем",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT): "Редактирование элемента с родителем",
mod_table_operate.ButtonNames.DEL: "❌ Удалить мою подписку",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите подписку:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, подписку не найден
''',
mod_table_operate.Messages.OPEN: f'''
<b>Подписку:</b>
<b>Название модуля:</b> #{mod_name_field}
<b>Тип:</b> #{type_field}
<b>Номер элемента:</b> #{item_id_field}
<b>Время создания:</b> #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): '''
Создание подписки. Шаг 1
Введите название модуля:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.SUBSCRIBE_TYPE): '''
Создание подписки. Шаг 2
Введите тип подписки:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.ITEM_ID): '''
Создание подписки. Шаг 3
Номер элемента или его родителя, на который нужно подписаться (-1, если элемента нет):
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Подписка успешно добавлена!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите подписку, который вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f'''
Текущее название модуля:
#{mod_name_field}
Введите новое название модуля:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.SUBSCRIBE_TYPE): f'''
Текущий тип подписки:
#{type_field}
Введите новый тип подписки:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ITEM_ID): f'''
Текущий номер элемента: #{item_id_field}
Введите новый номер элемента:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к подписке:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Подписка успешно отредактирована!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите подписку, которую вы хотите удалить.
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Подписка успешно удалёна!''',
}
# TODO Возможно это не нужно есть же mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_ADD) см. выше
messages_subs_type_status = {
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_ADD): f'''Добавление элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_DEL): f'''Удаление элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_EDIT): f'''Редактирование элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ITEM_DEL): f'''Удаление конкретного элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ITEM_EDIT): f'''Редактирование конкретного элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT): f'''Добавление элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT): f'''Удаление элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT): f'''Редактирование элемента''',
}
messages.update(messages_subs_type_status)
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID):
user_id = str(a_Message.from_user.id)
return bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName)(user_id)
return GetBDItems
class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
def __init__(self, a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName):
super().__init__(a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName)
def GetItemsFunc(self):
return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName)
def IsFirst(self):
return True
class ModuleSubscribe(mod_table_operate.TableOperateModule):
def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_DefInitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName)
def AddBDItemFunc(self, a_ItemData, a_UserID):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
a_ItemData[parent_id_field] = a_UserID
return super().AddBDItemFunc(a_ItemData, a_UserID)
def RegisterHandlers(self):
super().RegisterHandlers()
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc
GetAccess = self.m_GetAccessFunc
defaul_keyboard_func = self.m_GetStartKeyboardButtonsFunc
parent_table_name = None
parent_key_name = None
if self.m_ParentModName:
parent_mod = self.GetModule(self.m_ParentModName)
parent_table_name = parent_mod.m_Table.GetName()
parent_key_name = parent_mod.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
def GetButtonNameAndKeyValueAndAccess(self, a_Item):
type_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.SUBSCRIBE_TYPE)
item_id_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ITEM_ID)
n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item)
return n + ":" + str(a_Item[type_field_id]) + ":" + str(a_Item[item_id_field_id]), k, a
class ModuleUserSubscribe(ModuleSubscribe):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
self.UpdateSubscribes()
def GetName(self):
return module_name
def UpdateSubscribes(self):
self.m_BotSubscribes.Clear()
mod_name_id_field = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME)
subscribe_type_id_field = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.SUBSCRIBE_TYPE)
item_id_id_field = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ITEM_ID)
user_id_id_field = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
table_name = self.m_Table.GetName()
s_bd = bd_item.GetAllItemsTemplate(self.m_Bot, table_name)()
if s_bd:
for s in s_bd:
a_ModuleName = s[mod_name_id_field]
a_Type = s[subscribe_type_id_field]
a_ItemID = s[item_id_id_field]
a_UserID = s[user_id_id_field]
for t in bot_subscribes.SubscribeType:
k = mod_table_operate.EnumButton(t)
m = button_names.get(k, None)
if m and m == a_Type:
a_Type = t
break
self.m_BotSubscribes.AddSubscribe(a_UserID, a_ModuleName, a_Type, a_ItemID)
def OnChange(self):
self.UpdateSubscribes()

70
bot_modules/tasks.py

@ -3,9 +3,28 @@
# Задачи # Задачи
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message from bot_modules import mod_table_operate, mod_simple_message
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMCreateTask(StatesGroup):
name = State()
desc = State()
photo = State()
class FSMEditTaskPhotoItem(StatesGroup):
item_field = State()
class FSMEditTaskNameItem(StatesGroup):
item_field = State()
class FSMEditTaskDescItem(StatesGroup):
item_field = State()
class FSMEditTaskAccessItem(StatesGroup):
item_field = State()
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
module_name = 'tasks' module_name = 'tasks'
@ -23,7 +42,7 @@ table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT), bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR), bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR), bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO), bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR), bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR), bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT), bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
@ -31,6 +50,14 @@ table = bd_table.Table(table_name, [
init_access = f'{user_access.user_access_group_new}=va' init_access = f'{user_access.user_access_group_new}=va'
fsm = {
mod_table_operate.FSMs.CREATE: FSMCreateTask,
mod_table_operate.FSMs.EDIT_NAME: FSMEditTaskNameItem,
mod_table_operate.FSMs.EDIT_DESC: FSMEditTaskDescItem,
mod_table_operate.FSMs.EDIT_PHOTO: FSMEditTaskPhotoItem,
mod_table_operate.FSMs.EDIT_ACCESS: FSMEditTaskAccessItem,
}
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -39,10 +66,10 @@ button_names = {
mod_table_operate.ButtonNames.LIST: "📃 Список задач", mod_table_operate.ButtonNames.LIST: "📃 Список задач",
mod_table_operate.ButtonNames.ADD: "☑ Добавить задачу", mod_table_operate.ButtonNames.ADD: "☑ Добавить задачу",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать задачу", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать задачу",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение у задачи", mod_table_operate.ButtonNames.EDIT_PHOTO: "☐ Изменить изображение у задачи",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название у задачи", mod_table_operate.ButtonNames.EDIT_NAME: "≂ Изменить название у задачи",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание у задачи", mod_table_operate.ButtonNames.EDIT_DESC: "𝌴 Изменить описание у задачи",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к задаче", mod_table_operate.ButtonNames.EDIT_ACCESS: "✋ Изменить доступ к задаче",
mod_table_operate.ButtonNames.DEL: "❌ Удалить задачу", mod_table_operate.ButtonNames.DEL: "❌ Удалить задачу",
} }
@ -64,17 +91,17 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): ''' mod_table_operate.Messages.CREATE_NAME: '''
Создание задачи. Шаг 1 Создание задачи. Шаг 1
Введите название задачи: Введите название задачи:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.Messages.CREATE_DESC: '''
Создание задачи. Шаг 2 Создание задачи. Шаг 2
Введите описание задачи: Введите описание задачи:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.CREATE_PHOTO: '''
Создание задачи. Шаг 3 Создание задачи. Шаг 3
Загрузите обложку для задачи (Фото): Загрузите обложку для задачи (Фото):
@ -87,23 +114,23 @@ messages = {
mod_table_operate.Messages.SELECT_TO_EDIT: ''' mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите задачу, которую вы хотите отредактировать. Выберите задачу, которую вы хотите отредактировать.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.Messages.EDIT_PHOTO: '''
Загрузите новую обложку для задачи (Фото): Загрузите новую обложку для задачи (Фото):
Она будет отображаться в её описании. Она будет отображаться в её описании.
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.Messages.EDIT_NAME: f'''
Текущее название задачи: Текущее название задачи:
#{name_field} #{name_field}
Введите новое название задачи: Введите новое название задачи:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.Messages.EDIT_DESC: f'''
Текущее описание задачи: Текущее описание задачи:
#{desc_field} #{desc_field}
Введите новое описание задачи: Введите новое описание задачи:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f''' mod_table_operate.Messages.EDIT_ACCESS: f'''
Текущий доступ к задаче: Текущий доступ к задаче:
#{access_field} #{access_field}
@ -119,22 +146,9 @@ messages = {
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Задача успешно удалёна!''', mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Задача успешно удалёна!''',
} }
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Задача создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Задача отредактирована''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Задача удалёна''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Задача отредактирована #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Задача удалёна #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Задача создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Задача отредактирована''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Задача удалёна''',
}
messages.update(messages_subscribes)
class ModuleTasks(mod_table_operate.TableOperateModule): class ModuleTasks(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log): def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log) super().__init__(table, messages, button_names, fsm, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

161
bot_modules/user_in_groups.py

@ -1,161 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Пользователи в группах
from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message
from bot_modules import access_utils, groups_utils
from template import bd_item, bd_item_add
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMAddUserInGroups(StatesGroup):
bd_item = State()
from enum import Enum
from enum import auto
# ---------------------------------------------------------
# БД
module_name = 'user_in_groups'
table_name = groups_utils.table_user_in_groups_name
key_name = 'user_in_groupsID'
name_field = groups_utils.user_id_field
access_field = 'user_in_groupsAccess'
create_datetime_field = 'user_in_groupsCreateDateTime'
parent_id_field = groups_utils.parent_id_field
table_user_id_field = bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR)
table_parent_id_field = bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT)
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
table_user_id_field,
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
table_parent_id_field,
],
[
[table_user_id_field, table_parent_id_field],
]
)
init_access = f'{user_access.user_access_group_new}=-'
# ---------------------------------------------------------
# Сообщения и кнопки
class ButtonNames(Enum):
ADD_USER = auto()
button_names = {
mod_simple_message.ButtonNames.START: "🗫 Пользователи в группах",
mod_table_operate.ButtonNames.LIST: "📃 Список пользователей в группах",
ButtonNames.ADD_USER: "✅ Добавить пользователя в группу",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Доступ к пользователю в группе",
mod_table_operate.ButtonNames.DEL: "❌ Удалить пользователя из группы",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите пользователя в группе:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, пользователь в группе не найден
''',
mod_table_operate.Messages.OPEN: f'''
<b>пользователь в группе: #{name_field}</b>
Группа: #{parent_id_field}
Время создания: #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): '''
Создание пользователя в группе.
Укажите ID пользователя:
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Пользователь успешно добавлен в группу!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите пользователя в группе, которого вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к пользователю в группе:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Пользователь в группе успешно отредактирован!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите пользователя в группе, которого вы хотите удалить.
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Пульзователь успешно удалён из группы!''',
}
class ModuleUserInGroups(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name
def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
t_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
cur_buttons = [
keyboard.ButtonWithAccess(self.GetButton(ButtonNames.ADD_USER), user_access.AccessMode.ADD, self.GetAccess()),
]
return t_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
def RegisterHandlers(self):
super().RegisterHandlers()
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc
GetAccess = self.m_GetAccessFunc
defaul_keyboard_func = self.m_GetStartKeyboardButtonsFunc
parent_table_name = None
parent_key_name = None
if self.m_ParentModName:
parent_mod = self.GetModule(self.m_ParentModName)
parent_table_name = parent_mod.m_Table.GetName()
parent_key_name = parent_mod.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
# Добавление
a_ButtonName = self.GetButton(ButtonNames.ADD_USER)
if a_ButtonName:
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.ADD, only_parent = True)
check_func = bd_item.GetCheckForTextFunc(a_ButtonName)
if a_Prefix:
check_func = bd_item.GetCheckForPrefixFunc(a_Prefix)
bd_item_add.AddBDItem1RegisterHandlers(self.m_Bot,\
check_func,\
FSMAddUserInGroups,\
self.m_AddBDItemFunc,\
self.ShowMessageTemplate(self.GetMessage(mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME))),\
self.ShowMessageTemplate(self.GetMessage(mod_table_operate.Messages.SUCCESS_CREATE)),\
a_Prefix,\
parent_table_name,\
parent_key_name,\
name_field,\
GetButtonNameAndKeyValueAndAccess,\
GetAccess,\
defaul_keyboard_func,\
bd_item.FieldType.text,\
access_mode = user_access.AccessMode.ADD\
)

143
bot_modules/user_message.py

@ -1,143 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Сообщения пользователю
from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes, bot_messages, interfaces
from bot_modules import mod_table_operate, mod_simple_message, users
# ---------------------------------------------------------
# БД
module_name = 'user_messge'
table_name = module_name
key_name = 'userMessageID'
desc_field = 'messageText'
access_field = 'catAccess'
create_datetime_field = 'catCreateDateTime'
parent_id_field = users.key_name
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(desc_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
bd_table.TableField(parent_id_field, bd_table.TableFieldDestiny.PARENT_ID, bd_table.TableFieldType.INT),
])
init_access = f'{user_access.user_access_group_new}=-'
# ---------------------------------------------------------
# Сообщения и кнопки
button_names = {
mod_simple_message.ButtonNames.START: "📩 Сообщения для польователей",
mod_table_operate.ButtonNames.LIST: "📃 Список отправленных сообщений",
mod_table_operate.ButtonNames.ADD: "📨 Отправить сообщение",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать сообщение",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к сообщению",
mod_table_operate.ButtonNames.DEL: "❌ Удалить отправленное сообщение",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите сообщение:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, сообщение не найдено
''',
mod_table_operate.Messages.OPEN: f'''
<b>Категория: </b>
Пользоватеель: #{parent_id_field}
Текст сообщения: #{desc_field}
Время создания: #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): '''
Отправка сообщения
Введите текст сообщения:
''',
mod_table_operate.Messages.SUCCESS_CREATE: f'''✅ Сообщение успешно отправлено пользователю!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите проект, который вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f'''
Текущий текст сообщения:
#{desc_field}
Введите новый текст:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к сообщению:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Сообщение успешно отредактировано!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите категорию, которую вы хотите удалить.
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Сообщение успешно удалёно!''',
}
messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Сообщение создано''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):f'''Сообщение отредактировано''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL):f'''Сообщение удалено''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Сообщение отредактировано #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_DEL):f'''Сообщение удалено #item_id''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD_WITH_PARENT):f'''Сообщение создано''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT_WITH_PARENT):f'''Сообщение отредактировано''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_DEL_WITH_PARENT):f'''Сообщение удалено''',
}
messages.update(messages_subscribes)
class ModuleUserMessage(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name
async def AddBDItemFunc(self, a_ItemData, a_UserID):
res, error = await super().AddBDItemFunc(a_ItemData, a_UserID)
desc_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DESC)
user_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
if not await self.SendMessageToUser(bot_messages.MakeBotMessage(a_ItemData[desc_field]), a_ItemData[user_id_field], parse_mode=interfaces.ParseMode.HTML.value):
return None, '❌ Ошибка отправки сообщения'
return res, error
def GetStartButtons(self, a_Message, a_UserGroups):
return [
[mod_table_operate.ButtonNames.ADD, user_access.AccessMode.ADD],
[mod_table_operate.ButtonNames.LIST, user_access.AccessMode.VIEW],
[mod_table_operate.ButtonNames.EDIT, user_access.AccessMode.EDIT],
[mod_table_operate.ButtonNames.DEL, user_access.AccessMode.DELETE],
]
def GetButtonNameAndKeyValueAndAccess(self, a_Item):
key_name_id = self.GetKeyFieldID()
date_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.CREATE_DATE)
access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)
assert key_name_id != None
assert date_field_id != None
assert access_field_id != None
return \
a_Item[date_field_id],\
a_Item[key_name_id],\
a_Item[access_field_id]

168
bot_modules/users.py

@ -1,168 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Пользователи
from bot_sys import bot_bd, keyboard, user_access, bd_table
from bot_modules import mod_table_operate, mod_simple_message
from bot_modules import access_utils, groups_utils, groups, user_in_groups
# ---------------------------------------------------------
# БД
module_name = 'users'
table_name = module_name
key_name = 'user_id'
name_field = 'userName'
name1_field = 'userFirstName'
name2_field = 'userLastName'
is_bot_field = 'userIsBot'
language_code_field = 'userLanguageCode'
photo_field = 'userPhoto'
access_field = 'userAccess'
create_datetime_field = 'createDateTime'
table = bd_table.Table(table_name, [
bd_table.TableField(key_name, bd_table.TableFieldDestiny.KEY, bd_table.TableFieldType.INT),
bd_table.TableField(name_field, bd_table.TableFieldDestiny.NAME, bd_table.TableFieldType.STR),
bd_table.TableField(name1_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(name2_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(is_bot_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(language_code_field, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldType.STR),
bd_table.TableField(photo_field, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldType.PHOTO),
bd_table.TableField(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
bd_table.TableField(create_datetime_field, bd_table.TableFieldDestiny.CREATE_DATE, bd_table.TableFieldType.STR),
])
init_access = f'{user_access.user_access_group_new}=v'
# ---------------------------------------------------------
# Сообщения и кнопки
button_names = {
mod_simple_message.ButtonNames.START: "👤 Пользователи",
mod_table_operate.ButtonNames.LIST: "📃 Список пользователей",
# mod_table_operate.ButtonNames.ADD: "✅ Добавить пользователя",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать пользователя",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в пользователяе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в пользователяе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в пользователяе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к пользователю",
mod_table_operate.ButtonNames.DEL: "❌ Удалить пользователя",
}
messages = {
mod_simple_message.Messages.START: f'''
<b>{button_names[mod_simple_message.ButtonNames.START]}</b>
''',
mod_table_operate.Messages.SELECT: '''
Пожалуйста, выберите пользователя:
''',
mod_table_operate.Messages.ERROR_FIND: '''
Ошибка, пользователя не найден
''',
mod_table_operate.Messages.OPEN: f'''
<b>Пользователь: #{name_field}</b>
<b>ID:</b> #{key_name}
<b>Имя:</b> @#{name_field}
<b>Имя1:</b> #{name1_field}
<b>Имя2:</b> #{name2_field}
<b>Код языка:</b> #{language_code_field}
<b>Дата добавления:</b> #{create_datetime_field}
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): '''
Создание пользователя. Шаг 1
Введите название пользователя:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): '''
Создание пользователя. Шаг 2
Введите описание пользователя:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): '''
Создание пользователя. Шаг 3
Загрузите обложку для пользователя (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Пользователь успешно добавлен!''',
mod_table_operate.Messages.START_EDIT: '''
Пожалуйста, выберите действие:
''',
mod_table_operate.Messages.SELECT_TO_EDIT: '''
Выберите пользователя, которого вы хотите отредактировать.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.PHOTO): '''
Загрузите новую обложку для пользователя (Фото):
Она будет отображаться в его описании.
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.NAME): f'''
Текущее название пользователя:
#{name_field}
Введите новое название пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f'''
Текущее описание пользователя:
#{name1_field}
Введите новое описание пользователя:
''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ACCESS): f'''
Текущий доступ к пользователю:
#{access_field}
{user_access.user_access_readme}
Введите новую строку доступа:
''',
mod_table_operate.Messages.SUCCESS_EDIT: '''✅ Пользователь успешно отредактирован!''',
mod_table_operate.Messages.SELECT_TO_DELETE: '''
Выберите пользователя, который вы хотите удалить.
''',
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Пользователь успешно удалён!''',
}
class ModuleUsers(mod_table_operate.TableOperateModule):
def __init__(self, a_ParentModName, a_ChildModName, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self):
return module_name
def GetButtonNameAndKeyValueAndAccess(self, a_Item):
key_name_id = self.GetKeyFieldID()
name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME)
access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)
assert key_name_id != None
assert name_field_id != None
assert access_field_id != None
return \
a_Item[name_field_id] + '(' + str(a_Item[key_name_id]) + ')',\
a_Item[key_name_id],\
a_Item[access_field_id]
# Работа с базой данных пользователей
# Добавление пользователя, если он уже есть, то игнорируем
def AddUser(a_Bot, a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode):
a_Bot.SQLRequest(f"INSERT OR IGNORE INTO users ({key_name}, {name_field}, {name1_field}, {name2_field}, {is_bot_field}, {language_code_field}, {photo_field}, {access_field}, {create_datetime_field}) VALUES (?, ?, ?, ?, ?, ?, 0, ?, {bot_bd.GetBDDateTimeNow()});",
commit=True, param = (a_UserID, a_UserName, a_UserName1, a_UserName2, a_UserIsBot, a_LanguageCode, access_utils.GetItemDefaultAccessForModule(a_Bot, module_name)))
user_groups = groups_utils.GetUserGroupData(a_Bot, a_UserID)
# Если пользователь не состоит ни в одной группе, то добавляем его в группу user_access.user_access_group_new
if len(user_groups.group_names_list) == 0:
new_group_id = a_Bot.SQLRequest(f'SELECT {groups.key_name} FROM {groups.table_name} WHERE {groups.name_field} = ?',
param = [user_access.user_access_group_new])
if new_group_id and new_group_id[0]:
a_Bot.SQLRequest(f"INSERT OR IGNORE INTO {user_in_groups.table_name} ({user_in_groups.name_field}, {user_in_groups.parent_id_field}, {user_in_groups.access_field}, {user_in_groups.create_datetime_field}) VALUES (?, ?, ?, {bot_bd.GetBDDateTimeNow()});",
commit=True, param = (a_UserID, new_group_id[0][0], access_utils.GetItemDefaultAccessForModule(a_Bot, module_name)))
def GetUserInfo(a_Bot, a_UserID):
user_info = a_Bot.SQLRequest('SELECT * FROM users WHERE user_id = ?', param = [a_UserID])
if len(user_info) != 0:
return user_info[0]
return None

110
bot_modules/users_groups_agregator.py

@ -1,110 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Группы пользователей
from bot_sys import keyboard, user_access, bot_bd
from bot_modules import mod_simple_message, users, groups, user_in_groups
from template import simple_message, sql_request, bd_item
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
class FSMRequestToBD(StatesGroup):
sqlRequest = State()
# ---------------------------------------------------------
# БД
module_name = 'users_groups_agregator'
# ---------------------------------------------------------
# Сообщения
request_start_message = f'''
**Задайте запрос к БД**
Можете воспользоваться следующими шаблонами:
1. `SELECT * FROM {users.table_name}` - Все пользователи
2. `SELECT {groups.key_name}, {groups.name_field} FROM {groups.table_name}` - Все группы пользоватлей
3. `INSERT INTO {groups.table_name}({groups.name_field}) VALUES('GROUPNAME')` - добавление группы с именем GROUPNAME
4. `SELECT {user_in_groups.parent_id_field} FROM {user_in_groups.table_name} WHERE {user_in_groups.name_field} = USERID`- Все ID групп в которых состоит пользователь с USERID
5. `SELECT {groups.name_field} FROM {groups.table_name} WHERE {groups.name_field}=(SELECT groupid FROM {user_in_groups.table_name} WHERE {user_in_groups.name_field} = USERID)` - Все имена групп пользователя с USERID
6. `INSERT INTO {user_in_groups.table_name}({user_in_groups.name_field}, {user_in_groups.parent_id_field}) VALUES(USERID, GROUPID)` - добавление пользователя USERID в группу с GROUPID
'''
help_message = '''
📄 Существует две БД для работы с группами
`user_groups (group_id, groupName)` - содержит названия групп
`user_in_groups(user_id, group_id)` - содержит соответсвия ID пользователей и групп
'''
sql_request_button_name = "⛃ Запрос к БД для редактирования групп"
help_button_name = "📄 Информация по группам"
button_names = {
mod_simple_message.ButtonNames.START: "▦ Группы и пользователи",
}
messages = {
mod_simple_message.Messages.START: '''
<b>Группы пользователей находятся в стадии разработки</b>
Пока можете воспользоваться хардкорным способом через запросы к БД
''',
}
init_access = f'{user_access.user_access_group_new}=-'
class ModuleUsersGroupsAgregator(mod_simple_message.SimpleMessageModule):
def __init__(self, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log):
super().__init__(messages, button_names, init_access, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
self.m_SqlRequestButtonName = self.CreateButton('sql request', sql_request_button_name)
self.m_RequestStartMessage = self.CreateMessage('equest start', request_start_message)
self.m_HelpButtonName = self.CreateButton('help', help_button_name)
self.m_HelpMessage = self.CreateMessage('help', help_message)
self.m_HelpMessageHandler = simple_message.InfoMessageTemplate(
self.m_Bot,
self.m_HelpMessage,
self.m_GetStartKeyboardButtonsFunc,
None,
self.m_GetAccessFunc
)
def GetName(self):
return module_name
def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
mod_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
cur_buttons = [
keyboard.ButtonWithAccess(self.m_SqlRequestButtonName, user_access.AccessMode.EDIT, self.GetAccess()),
keyboard.ButtonWithAccess(self.m_HelpButtonName , user_access.AccessMode.VIEW, self.GetAccess())
]
return mod_buttons + keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
def RegisterHandlers(self):
super().RegisterHandlers()
sql_request.RequestToBDRegisterHandlers(
self.m_Bot,
self.m_SqlRequestButtonName,
self.m_RequestStartMessage,
FSMRequestToBD,
self.m_GetStartKeyboardButtonsFunc,
user_access.AccessMode.EDIT,
self.m_GetAccessFunc
)
self.m_Bot.RegisterMessageHandler(
self.m_HelpMessageHandler,
bd_item.GetCheckForTextFunc(self.m_HelpButtonName)
)
def AddUserInGroup(a_Bot, a_UserID, a_GroupName):
g_id = a_Bot.SQLRequest(f'SELECT {groups.key_name} FROM {groups.table_name} WHERE {groups.name_field} = "{a_GroupName}"');
if not g_id or len(g_id) != 1 or len(g_id[0]) != 1:
return False
group_id = g_id[0][0]
r = f'INSERT OR IGNORE INTO {user_in_groups.table_name}({user_in_groups.name_field}, {user_in_groups.parent_id_field}) VALUES(?, ?)'
result = a_Bot.SQLRequest(r, commit=True, param = (a_UserID, group_id))

24
bot_sys/aiogram_bot.py

@ -9,16 +9,6 @@ from aiogram.dispatcher import Dispatcher
from aiogram.contrib.fsm_storage.memory import MemoryStorage from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.utils import executor from aiogram.utils import executor
def GetPhotoList(a_PhotoIDs):
if not a_PhotoIDs or a_PhotoIDs == 0:
return []
photos = a_PhotoIDs.split(",")
result = []
for p in photos:
if p != '0' and p != '':
result += [p]
return result
class AiogramBot(interfaces.IBot): class AiogramBot(interfaces.IBot):
def __init__(self, a_TelegramBotApiToken, a_BDFileName, a_RootIDs, a_Log): def __init__(self, a_TelegramBotApiToken, a_BDFileName, a_RootIDs, a_Log):
self.m_TelegramBotApiToken = a_TelegramBotApiToken self.m_TelegramBotApiToken = a_TelegramBotApiToken
@ -49,27 +39,19 @@ class AiogramBot(interfaces.IBot):
base_keyboards = [keyboard.MakeAiogramKeyboard(a_KeyboardButtons)] base_keyboards = [keyboard.MakeAiogramKeyboard(a_KeyboardButtons)]
if inline_keyboards: if inline_keyboards:
base_keyboards = inline_keyboards base_keyboards = inline_keyboards
photos = GetPhotoList(a_PhotoIDs) if a_PhotoIDs and a_PhotoIDs != 0 and a_PhotoIDs != '0':
if len(photos) > 0:
for p in photos[:-1]:
await self.m_TBot.send_photo(
a_UserID,
p,
''
)
p = photos[-1]
if base_keyboards: if base_keyboards:
for k in base_keyboards: for k in base_keyboards:
await self.m_TBot.send_photo( await self.m_TBot.send_photo(
a_UserID, a_UserID,
p, a_PhotoIDs,
a_Message, a_Message,
reply_markup = k reply_markup = k
) )
else: else:
await self.m_TBot.send_photo( await self.m_TBot.send_photo(
a_UserID, a_UserID,
p, a_PhotoIDs,
a_Message a_Message
) )
else: else:

73
bot_sys/bd_table.py

@ -6,19 +6,8 @@ from enum import auto
# Тип поля в таблице # Тип поля в таблице
class TableFieldType(Enum): class TableFieldType(Enum):
INT = auto() INT = 'INTEGER'
STR = auto() STR = 'TEXT'
ENUM = auto()
PHOTO = auto()
def InitTableType(a_TableFieldType):
types = {
TableFieldType.INT: 'INTEGER',
TableFieldType.STR: 'TEXT',
TableFieldType.ENUM: 'TEXT',
TableFieldType.PHOTO: 'TEXT',
}
return types.get(a_TableFieldType, None)
# Предназначение поля в таблице # Предназначение поля в таблице
class TableFieldDestiny(Enum): class TableFieldDestiny(Enum):
@ -26,34 +15,17 @@ class TableFieldDestiny(Enum):
NAME = auto() NAME = auto()
DESC = auto() DESC = auto()
PHOTO = auto() PHOTO = auto()
PHOTO_PAY = auto()
ACCESS = auto() ACCESS = auto()
DEFAULT_ACCESS = auto() DEFAULT_ACCESS = auto()
CREATE_DATE = auto() CREATE_DATE = auto()
PARENT_ID = auto() PARENT_ID = auto()
STATUS = auto()
SUBSCRIBE_TYPE = auto()
ITEM_ID = auto()
ADDRESS = auto()
OTHER = auto() OTHER = auto()
VERSION_NUMBER = auto()
SUB_VERSION_NUMBER = auto()
USER_ID = auto()
USER_NAME = auto() # Имя
USER_FAMILY_NAME = auto() # Фамилия
USER_MIDDLE_NAME = auto() # Отчество
USER_BIRTHDAY = auto() # Дата рождения
USER_ADDRESS = auto() # Адресс
USER_CONTACTS = auto() # контакты
USER_CONFIRM = auto() # подтверждение
AUTH_PHOTO_DOCS = auto()
class TableField: class TableField:
def __init__(self, a_Name, a_Destiny : TableFieldDestiny, a_Type : TableFieldType, a_Enum = None): def __init__(self, a_Name, a_Destiny : TableFieldDestiny, a_Type : TableFieldType):
self.m_Name = a_Name self.m_Name = a_Name
self.m_Destiny = a_Destiny self.m_Destiny = a_Destiny
self.m_Type = a_Type self.m_Type = a_Type
self.m_Enum = a_Enum
class Table: class Table:
def __init__(self, a_TableName, a_Fields : [TableField], a_UniqueFields = None): def __init__(self, a_TableName, a_Fields : [TableField], a_UniqueFields = None):
@ -65,7 +37,7 @@ class Table:
return self.m_TableName return self.m_TableName
def GetFields(self): def GetFields(self):
return self.m_Fields return self.TableFieldType
def GetFieldsCount(self): def GetFieldsCount(self):
return len(self.m_Fields) return len(self.m_Fields)
@ -93,7 +65,7 @@ class Table:
request = f'CREATE TABLE IF NOT EXISTS {self.GetName()}(' request = f'CREATE TABLE IF NOT EXISTS {self.GetName()}('
items = [] items = []
for f in self.m_Fields: for f in self.m_Fields:
item = f.m_Name + ' ' + str(InitTableType(f.m_Type)) item = f.m_Name + ' ' + str(f.m_Type.value)
if f.m_Destiny == TableFieldDestiny.KEY: if f.m_Destiny == TableFieldDestiny.KEY:
item += ' PRIMARY KEY' item += ' PRIMARY KEY'
items += [item] items += [item]
@ -109,32 +81,17 @@ class Table:
result = a_String result = a_String
for i in range(len(self.m_Fields)): for i in range(len(self.m_Fields)):
f = self.m_Fields[i] f = self.m_Fields[i]
name = f'#{f.m_Name}' result = result.replace(f'#{f.m_Name}', str(a_BDItem[i]))
result = result.replace('<code>' + name + '</code>', '<code>' + str(a_BDItem[i]).replace('\n', '</code>\n<code>') + '</code>')
result = result.replace(name, str(a_BDItem[i]))
return result
def ReplaceAllFieldTagsByDict(self, a_String, a_BDItemDict):
result = a_String
for f in self.m_Fields:
if f.m_Name in a_BDItemDict:
result = result.replace(f'#{f.m_Name}', str(a_BDItemDict[f.m_Name]))
return result return result
class Status(Enum):
NEW = auto()
FINISH = auto()
def Test(): def Test():
f1 = TableField('f1', TableFieldDestiny.KEY, TableFieldType.INT) f1 = TableField('f1', TableFieldDestiny.KEY, TableFieldType.INT)
f2 = TableField('f2', TableFieldDestiny.NAME, TableFieldType.STR) f2 = TableField('f2', TableFieldDestiny.NAME, TableFieldType.STR)
f3 = TableField('f3', TableFieldDestiny.DESC, TableFieldType.STR) f3 = TableField('f3', TableFieldDestiny.DESC, TableFieldType.STR)
f4 = TableField('f4', TableFieldDestiny.STATUS, TableFieldType.ENUM, a_Enum = Status)
table = Table('tname', [ table = Table('tname', [
f1, f1,
f2, f2,
f3, f3
f4,
], ],
[[f1], [f2, f3]] [[f1], [f2, f3]]
) )
@ -154,23 +111,15 @@ def Test():
assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Destiny == TableFieldDestiny.DESC assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Destiny == TableFieldDestiny.DESC
assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Type == TableFieldType.STR assert table.GetFieldByDestiny(TableFieldDestiny.DESC).m_Type == TableFieldType.STR
assert table.GetFieldIDByDestiny(TableFieldDestiny.DESC) == 2 assert table.GetFieldIDByDestiny(TableFieldDestiny.DESC) == 2
assert table.GetFieldByDestiny(TableFieldDestiny.STATUS).m_Name == 'f4'
assert table.GetFieldNameByDestiny(TableFieldDestiny.STATUS) == 'f4'
assert table.GetFieldByDestiny(TableFieldDestiny.STATUS).m_Destiny == TableFieldDestiny.STATUS
assert table.GetFieldByDestiny(TableFieldDestiny.STATUS).m_Type == TableFieldType.ENUM
assert table.GetFieldIDByDestiny(TableFieldDestiny.STATUS) == 3
assert table.GetFieldByDestiny(TableFieldDestiny.PHOTO) == None assert table.GetFieldByDestiny(TableFieldDestiny.PHOTO) == None
assert table.GetFieldIDByDestiny(TableFieldDestiny.PHOTO) == None assert table.GetFieldIDByDestiny(TableFieldDestiny.PHOTO) == None
assert table.GetFieldNameByDestiny(TableFieldDestiny.PHOTO) == None assert table.GetFieldNameByDestiny(TableFieldDestiny.PHOTO) == None
assert table.GetFieldsCount() == 4 assert table.GetFieldsCount() == 3
assert len(table.GetFields()) == 4
print(table.GetInitTableRequest()) print(table.GetInitTableRequest())
assert table.GetInitTableRequest() == 'CREATE TABLE IF NOT EXISTS tname(f1 INTEGER PRIMARY KEY, f2 TEXT, f3 TEXT, f4 TEXT, UNIQUE(f1), UNIQUE(f2, f3));' assert table.GetInitTableRequest() == 'CREATE TABLE IF NOT EXISTS tname(f1 INTEGER PRIMARY KEY, f2 TEXT, f3 TEXT, UNIQUE(f1), UNIQUE(f2, f3));'
item = [10, 'i2\ni2.1', 'i3', 'i4']
assert table.ReplaceAllFieldTags('#f1 #f2 #f3 #f4', item) == '10 i2\ni2.1 i3 i4'
assert table.ReplaceAllFieldTags('#f1 <code>#f2</code> <code>#f3</code> #f4', item) == '10 <code>i2</code>\n<code>i2.1</code> <code>i3</code> i4', table.ReplaceAllFieldTags('f1 <code>#f2</code> <code>#f3</code> #f4', item) item = [10, 'i1', 'i2']
assert table.ReplaceAllFieldTags('#f1 #f2 #f3', item) == '10 i1 i2'

2
bot_sys/bot_bd.py

@ -9,7 +9,6 @@ from bot_sys import log
def GetBDDateTimeNow(): def GetBDDateTimeNow():
return 'datetime(\'now\')' return 'datetime(\'now\')'
# TODO: Удалить что-то из SelectBDTemplate RequestSelectTemplate
def SelectBDTemplate(a_Bot, a_TableName): def SelectBDTemplate(a_Bot, a_TableName):
def SelectBD(): def SelectBD():
return a_Bot.SQLRequest(f'SELECT * FROM {a_TableName}') return a_Bot.SQLRequest(f'SELECT * FROM {a_TableName}')
@ -21,7 +20,6 @@ def RequestSelectTemplate(a_Bot, a_TableName):
return SelectBD return SelectBD
def SQLRequest(a_Log, a_BDFileName, a_Request : str, commit = False, return_error = False, param = None): def SQLRequest(a_Log, a_BDFileName, a_Request : str, commit = False, return_error = False, param = None):
#print('SQLRequest', a_Request, commit)
db = sqlite3.connect(a_BDFileName) db = sqlite3.connect(a_BDFileName)
cursor = db.cursor() cursor = db.cursor()
result = [] result = []

42
bot_sys/bot_messages.py

@ -37,40 +37,23 @@ class BotMessage:
msg = self.GetMessageForLang(self.m_Language) msg = self.GetMessageForLang(self.m_Language)
return msg.GetDesc() return msg.GetDesc()
def GetCurLang(self, a_Language):
msg = self.m_BotMessages.GetMessages()
if not msg.get(a_Language, None):
a_Language = self.m_Language
if not msg.get(a_Language, None):
a_Language = self.m_BotMessages.a_DefaultLanguage
return a_Language
def FindMessageForLang(self, a_Name, a_Language):
if not self.m_BotMessages:
return None
msg = self.m_BotMessages.GetMessages()
a_Language = self.GetCurLang(a_Language)
if not msg.get(a_Language, None):
return None
new_msg = msg[a_Language].get(a_Name, None)
return new_msg
def GetMessageForLang(self, a_Language): def GetMessageForLang(self, a_Language):
if not self.m_BotMessages: if not self.m_BotMessages:
return self return self
last_update = self.m_BotMessages.m_LastUpdate last_update = self.m_BotMessages.m_LastUpdate
new_msg = self new_msg = self
if self.m_DateTime < last_update: if self.m_DateTime < last_update:
a_Language = self.GetCurLang(a_Language) msg = self.m_BotMessages.GetMessages()
new_msg = self.FindMessageForLang(self.m_MessageName, a_Language) if not msg.get(a_Language, None):
if not new_msg: a_Language = self.m_Language
new_msg = self if not msg.get(a_Language, None):
elif a_Language == self.m_Language: a_Language = self.m_BotMessages.a_DefaultLanguage
new_msg = msg[a_Language].get(self.m_MessageName, self)
if a_Language == self.m_Language:
self.m_MessageDesc = new_msg.m_MessageDesc self.m_MessageDesc = new_msg.m_MessageDesc
self.m_Language = new_msg.m_Language self.m_Language = new_msg.m_Language
self.m_PhotoID = new_msg.m_PhotoID self.m_PhotoID = new_msg.m_PhotoID
self.m_DateTime = last_update self.m_DateTime = new_msg.m_DateTime
return new_msg return new_msg
def MakeBotMessage(a_MessageDesc): def MakeBotMessage(a_MessageDesc):
@ -85,15 +68,6 @@ class BotMessages:
def GetMessages(self): def GetMessages(self):
return self.m_Messages return self.m_Messages
def CheckDescExist(self, a_MessageDesc):
msg = self.GetMessages()
for l, m in msg.items():
for name, cur_msg in m.items():
if cur_msg.GetDesc() == a_MessageDesc:
return True
return False
def UpdateSignal(self, a_DateTime): def UpdateSignal(self, a_DateTime):
self.m_LastUpdate = a_DateTime self.m_LastUpdate = a_DateTime

76
bot_sys/bot_subscribes.py

@ -1,76 +0,0 @@
#-*-coding utf-8-*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Работа с подписками
from enum import Enum
from enum import auto
# Тип поля в таблице
class SubscribeType(Enum):
ANY_ITEM_ADD = auto()
ANY_ITEM_DEL = auto()
ANY_ITEM_EDIT = auto()
ITEM_DEL = auto()
ITEM_EDIT = auto()
ANY_ITEM_ADD_WITH_PARENT = auto()
ANY_ITEM_DEL_WITH_PARENT = auto()
ANY_ITEM_EDIT_WITH_PARENT = auto()
class BotSubscribes:
def __init__(self):
self.Clear()
def GetSubscribes(self):
return self.m_Subscribes
def Clear(self):
self.m_Subscribes = {}
def GetUserIDs(self, a_ModuleName, a_Type, a_ItemID = -1):
s = self.GetSubscribes()
ids = set()
for user_id, su in s.items():
sub_um = su.get(a_ModuleName, None)
if sub_um:
i = sub_um.get(str(a_Type), None)
if i == str(a_ItemID):
ids.add(user_id)
return ids
def AddSubscribe(self, a_UserID, a_ModuleName, a_Type, a_ItemID = -1):
s = self.GetSubscribes()
if not s.get(a_UserID, None):
s[a_UserID] = {}
if not s[a_UserID].get(a_ModuleName, None):
s[a_UserID][a_ModuleName] = {}
s[a_UserID][a_ModuleName][str(a_Type)] = str(a_ItemID)
def Test():
a = set()
a.add(1)
a.add(2)
a.add(1)
assert 1 in a
assert not 3 in a
user_id_1 = '123'
user_id_2 = '34234'
user_id_3 = '4234'
mod_1 = 'proj'
mod_2 = 'backup'
s = BotSubscribes()
s.AddSubscribe(user_id_1, mod_1, SubscribeType.ANY_ITEM_ADD)
s.AddSubscribe(user_id_2, mod_2, SubscribeType.ITEM_DEL)
assert len(s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_ADD)) == 1
assert len(s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_DEL)) == 0
assert user_id_1 in s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_ADD)
assert not user_id_2 in s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_ADD)
assert not user_id_3 in s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_ADD)
assert len(s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)) == 1
assert len(s.GetUserIDs(mod_2, SubscribeType.ANY_ITEM_ADD)) == 0
assert user_id_2 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)
assert not user_id_1 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)
assert not user_id_3 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)

4
bot_sys/config.py

@ -24,9 +24,7 @@ root_ids_file_name = 'config_root_ids'
# Дополнительные функции # Дополнительные функции
def ClearReadLine(a_Line): def ClearReadLine(a_Line):
line = a_Line.strip() return a_Line[:-1]
return line
def GetFirstLineFromFile(a_FileName): def GetFirstLineFromFile(a_FileName):
f = open(a_FileName, 'r') f = open(a_FileName, 'r')

8
bot_sys/interfaces.py

@ -3,14 +3,6 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from enum import Enum
from enum import auto
# Способ форматирования
class ParseMode(Enum):
HTML = "HTML"
Markdown ='Markdown'
class IBot(ABC): class IBot(ABC):
@abstractmethod @abstractmethod
def GetRootIDs(self): def GetRootIDs(self):

1
bot_sys/keyboard.py

@ -40,7 +40,6 @@ def MakeButtons(a_Bot, a_ButtonList : [ButtonWithAccess], a_UserGroups):
if not b.label: if not b.label:
continue continue
label = str(b.label) label = str(b.label)
#print('MakeButtons', a_Bot.GetRootIDs(), b.access_string, a_UserGroups.user_id, a_UserGroups.group_names_list, b.access_mode)
if user_access.CheckAccess(a_Bot.GetRootIDs(), b.access_string, a_UserGroups, b.access_mode): if user_access.CheckAccess(a_Bot.GetRootIDs(), b.access_string, a_UserGroups, b.access_mode):
buttons += [types.KeyboardButton(label)] buttons += [types.KeyboardButton(label)]
step = GetButtonInRowCount(len(buttons)) step = GetButtonInRowCount(len(buttons))

2
bot_sys/log.py

@ -10,11 +10,11 @@
# Error - Ошибка. # Error - Ошибка.
# Success - Успех. # Success - Успех.
from bot_sys import config
import colorama import colorama
import datetime import datetime
colorama.init() colorama.init()
# TODO: Сообщения в файл не различются по Info Warn Error Success . Нужно добавить чтобы они различались
class Log: class Log:
def __init__(self, a_FileName): def __init__(self, a_FileName):
self.m_FileName = a_FileName self.m_FileName = a_FileName

141
bot_sys/test_bot.py

@ -0,0 +1,141 @@
#-*-coding utf-8-*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
from bot_sys import interfaces, bot_bd, keyboard, user_access, test_log
import asyncio
class UserData():
def __init__(self, a_id, a_username, a_first_name, a_last_name, a_is_bot, a_language_code):
self.id = a_id
self.username = a_username
self.first_name = a_first_name
self.last_name = a_last_name
self.is_bot = a_is_bot
self.language_code = a_language_code
class UserPhoto():
def __init__(self, a_PhotoID):
self.file_id = a_PhotoID
class UserMessage():
def __init__(self, a_UserData, a_Message, a_PhotoID):
self.from_user = a_UserData
self.text = a_Message
if not a_PhotoID:
self.photo = None
self.photo = [UserPhoto(a_PhotoID)]
class BotMessage():
def __init__(self, a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons, parse_mode = None):
self.m_Message = a_Message
self.m_PhotoIDs = a_PhotoIDs
self.m_KeyboardButtons = a_KeyboardButtons
self.m_InlineKeyboardButtons = a_InlineKeyboardButtons
self.m_parse_mode = parse_mode
class BotMessageHandler():
def __init__(self, a_MessageHandler, a_CheckFunc=None, commands=None, regexp=None, content_types=None, state=None):
self.m_MessageHandler = a_MessageHandler
self.m_CheckFunc = a_CheckFunc
self.m_commands = commands
self.m_regexp = regexp
self.m_content_types = content_types
self.m_state = state
class TestBot(interfaces.IBot):
def __init__(self, a_BDFileName, a_RootIDs, a_Log):
self.m_BDFileName = a_BDFileName
self.m_RootIDs = a_RootIDs
self.m_Log = a_Log
self.m_UserMessage = {}
self.m_BotMessage = {}
self.m_BotMessageHandlers = []
def SendUserMessage(self, a_UserData : UserData, a_Message, a_PhotoIDs):
user_id = a_UserData.id
if not self.m_UserMessage.get(user_id, None):
self.m_UserMessage[user_id] = []
self.m_UserMessage[user_id] += [UserMessage(a_UserData, a_Message, a_PhotoIDs)]
def GetBotMessage(self, a_UserID): # return [BotMessage]
result = self.m_BotMessage.get(a_UserID, None)
self.m_BotMessage[a_UserID] = []
return result
def GetRootIDs(self):
return self.m_RootIDs
def GetLog(self):
return self.m_Log
def SQLRequest(self, a_Request : str, commit = False, return_error = False, param = None):
return bot_bd.SQLRequest(self.m_Log, self.m_BDFileName, a_Request, commit = commit, return_error = return_error, param = param)
async def SendMessage(self, a_UserID, a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons, parse_mode = None):
self.m_BotMessage[a_UserID] = [BotMessage(a_Message, a_PhotoIDs, a_KeyboardButtons, a_InlineKeyboardButtons, parse_mode = parse_mode)]
async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons):
pass
def RegisterMessageHandler(self, a_MessageHandler, a_CheckFunc=None, commands=None, regexp=None, content_types=None, state=None):
self.m_BotMessageHandlers += [BotMessageHandler(a_MessageHandler, a_CheckFunc=a_CheckFunc, commands=commands, regexp=regexp, content_types=content_types, state=state)]
def RegisterCallbackHandler(self, a_CallbackHandler, a_CheckFunc=None, commands=None, regexp=None, content_types=None, state=None):
pass
def StartPolling(self):
for user_id, user_msgs in self.m_UserMessage.items():
for user_msg in user_msgs:
for message_handler in self.m_BotMessageHandlers:
check = False
if message_handler.m_CheckFunc:
check = m_CheckFunc(user_msg)
cmds = message_handler.m_commands
if cmds:
for c in cmds:
if '/'+ c == user_msg.text:
check = True
print('user_msg.text', user_msg.text, c, check)
# TODO : добавить обработку regexp content_types state
if check:
print('message_handler', message_handler.m_MessageHandler, user_msg)
asyncio.run(message_handler.m_MessageHandler(user_msg, state = message_handler.m_state))
self.m_UserMessage = {}
def Test():
print('Test')
log = test_log.TestLog()
root_id = '234353425'
a_RootIDs = [root_id]
a_BDFileName = 'test_bd.bd'
bot = TestBot(a_BDFileName, a_RootIDs, log)
user_kb = [['user_kb']]
user_ikb = [['user_ikb']]
user_parse_mode = 'html'
async def TestMessageHandler(a_Message, state = None):
user_id = str(a_Message.from_user.id)
print('user_id', user_id)
await bot.SendMessage(user_id, a_Message.text, a_Message.photo[0].file_id, user_kb, user_ikb, user_parse_mode)
bot.RegisterMessageHandler(TestMessageHandler, commands = ['start'])
user_photo_id = '435456567'
user_message = '/start'
user_data = UserData(root_id, 'a_username', 'a_first_name', 'a_last_name', 'False', 'ru')
bot.SendUserMessage(user_data, user_message, user_photo_id)
bot.StartPolling()
bot_messages = bot.GetBotMessage(root_id)
assert len(bot_messages) == 1
bot_message = bot_messages[0]
assert bot_message.m_Message == user_message
assert bot_message.m_PhotoIDs == user_photo_id
assert bot_message.m_KeyboardButtons[0][0] == user_kb[0][0]
assert bot_message.m_InlineKeyboardButtons[0][0] == user_ikb[0][0]
assert bot_message.m_parse_mode == user_parse_mode

51
bot_sys/test_log.py

@ -0,0 +1,51 @@
#-*-coding utf-8-*-
# Общественное достояние 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# ---------------------------------------------------------
# Логирование событий в список
# Четыре типа уведомлений:
# Info - Информация.
# Warn - Предупреждение.
# Error - Ошибка.
# Success - Успех.
class TestLog:
def __init__(self):
self.m_LogMessage = []
def GetLogMessage():
result = self.m_LogMessage
self.m_LogMessage = []
return result
def GetFileName(self):
return self.m_FileName
def GetTimeNow(self):
return datetime.datetime.now()
def GetTime(self):
now = self.GetTimeNow()
time = now.strftime(f"[%d.%m.%Y, %H:%M]")
return time
def Info(self, a_LogMessage):
time = self.GetTime()
self.WriteToList(f'{time} | {a_LogMessage}')
def Warn(self, a_LogMessage):
time = self.GetTime()
self.WriteToList(f'{time} | {a_LogMessage}')
def Error(self, a_LogMessage):
time = self.GetTime()
self.WriteToList(f'{time} | {a_LogMessage}')
def Success(self, a_LogMessage):
time = self.GetTime()
self.WriteToList(f'{time} | {a_LogMessage}')
def WriteToList(self, a_LogMessage):
self.m_LogMessage += [a_LogMessage]

4
bot_sys/user_access.py

@ -8,7 +8,6 @@ from bot_sys import config
user_access_group_all = 'all' user_access_group_all = 'all'
user_access_group_new = 'new' user_access_group_new = 'new'
user_access_group_auth_users = 'authorize_users'
user_access_readme = f''' user_access_readme = f'''
Доступ к пользователям задаётся в виде строки Доступ к пользователям задаётся в виде строки
@ -33,13 +32,11 @@ ACCEES_EDIT = 'r' - изменение прав доступа
# Типы уровня доступа # Типы уровня доступа
class AccessMode(Enum): class AccessMode(Enum):
NONE = '-'
VIEW = 'v' VIEW = 'v'
ADD = 'a' ADD = 'a'
EDIT = 'e' EDIT = 'e'
DELETE = 'd' DELETE = 'd'
ACCEES_EDIT = 'r' ACCEES_EDIT = 'r'
ALL = '+'
class UserGroups: class UserGroups:
def __init__(self, a_UserID : str, a_GroupNamesList : [str]): def __init__(self, a_UserID : str, a_GroupNamesList : [str]):
@ -58,7 +55,6 @@ def CheckAccessItem(a_AccessItem : str, a_AccessMode : AccessMode):
# Возвращает возможность доступа пользователю a_UserGroups в элемент с правами a_AccessValue по режиму доступа a_AccessMode # Возвращает возможность доступа пользователю a_UserGroups в элемент с правами a_AccessValue по режиму доступа a_AccessMode
def CheckAccess(a_RootIDs, a_AccessValue : str, a_UserGroups : UserGroups, a_AccessMode : AccessMode): def CheckAccess(a_RootIDs, a_AccessValue : str, a_UserGroups : UserGroups, a_AccessMode : AccessMode):
#print(a_RootIDs, a_AccessValue, a_UserGroups, a_AccessMode)
if a_UserGroups.user_id in a_RootIDs: if a_UserGroups.user_id in a_RootIDs:
return True return True
for i in a_AccessValue.split(';'): for i in a_AccessValue.split(';'):

1
config_auth_docs

@ -1 +0,0 @@
auth_docs/test_doc.html

BIN
logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

115
logo.svg

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="logo.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="0.46235269"
inkscape:cx="392.55746"
inkscape:cy="561.25984"
inkscape:window-width="1366"
inkscape:window-height="704"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2">
<rect
x="272.52362"
y="455.61329"
width="305.51046"
height="95.272684"
id="rect2623" />
<clipPath
id="clipPath18"
clipPathUnits="userSpaceOnUse">
<path
id="path16"
d="M 0,283.465 H 283.465 V 0 H 0 Z" />
</clipPath>
</defs>
<g
inkscape:label="Слой 1"
inkscape:groupmode="layer"
id="layer1">
<g
clip-path="url(#clipPath18)"
id="g14"
transform="matrix(0.12603901,0,0,-0.12603901,40.634086,141.93678)"
inkscape:export-filename="/home/alexei/CurProject/МИРОКОД/PlatformBot/logo.png"
inkscape:export-xdpi="363.41403"
inkscape:export-ydpi="363.41403">
<g
transform="translate(141.7347,229.1228)"
id="g20">
<path
id="path22"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c 13.018,-5.541 25.524,-12.205 37.383,-19.879 l 2.053,19.527 C 26.921,7.161 13.747,13.687 0,19.08 -13.796,13.667 -27.015,7.114 -39.57,-0.433 l 2.053,-19.533 C -25.619,-12.256 -13.067,-5.562 0,0" />
</g>
<g
transform="translate(197.2625,58.1423)"
id="g24">
<path
id="path26"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -13.756,-3.155 -27.811,-5.12 -41.983,-5.889 l 9.81,-16.991 c 14.84,1.298 29.335,3.794 43.372,7.436 7.89,12.312 14.762,25.332 20.555,38.923 L 18.613,38.074 C 13.521,24.892 7.301,12.143 0,0" />
</g>
<g
transform="translate(231.5555,163.7942)"
id="g28">
<path
id="path30"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="m 0,0 c -1.231,-14.124 -3.684,-28.09 -7.295,-41.733 l 19.22,4.085 c 3.228,14.124 5.34,28.673 6.213,43.556 -9.351,11.365 -19.647,21.919 -30.739,31.583 l -17.923,-7.98 C -19.559,20.584 -9.334,10.716 0,0" />
</g>
<g
transform="translate(51.909,163.7956)"
id="g32">
<path
id="path34"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C 9.318,10.697 19.524,20.551 30.468,29.465 L 12.547,37.444 C 1.476,27.793 -8.802,17.255 -18.138,5.908 c 0.872,-14.863 2.979,-29.393 6.2,-43.498 L 7.28,-41.675 C 3.676,-28.05 1.229,-14.103 0,0" />
</g>
<g
transform="translate(86.2034,58.1433)"
id="g36">
<path
id="path38"
style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none"
d="M 0,0 C -7.321,12.177 -13.553,24.963 -18.654,38.184 L -31.798,23.585 c 5.802,-13.629 12.689,-26.686 20.599,-39.029 14.035,-3.641 28.53,-6.139 43.366,-7.437 L 41.978,-5.89 C 27.808,-5.121 13.756,-3.155 0,0" />
</g>
</g>
<text
xml:space="preserve"
transform="matrix(0.45291788,0,0,0.89570042,-46.556351,-302.5624)"
id="text2621"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:40px;line-height:1.25;font-family:cmr10;-inkscape-font-specification:'cmr10, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0px;white-space:pre;shape-inside:url(#rect2623)"
inkscape:export-filename="/home/alexei/CurProject/МИРОКОД/PlatformBot/logo.png"
inkscape:export-xdpi="363.41403"
inkscape:export-ydpi="363.41403"><tspan
x="272.52344"
y="490.61328"
id="tspan5179">TPlatformBot</tspan></text>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 4.6 KiB

118
main.py

@ -1,32 +1,24 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> # Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
import os log_start_message = 'Бот успешно запущен!'
from bot_sys import config, log, aiogram_bot, bot_messages, bd_table, user_access
from bot_modules import mod_agregator, start, profile, backup, users_groups_agregator, access, projects, tasks, needs, comments
from bot_modules import languages, messages, buttons, users, groups, user_in_groups
from bot_modules import orders_cat, orders, all_orders, authorize
from bot_modules import user_message
from bot_modules import bd_version
from bot_sys import bot_subscribes import os
from bot_modules import subscribes
log_start_message = 'Бот успешно запущен!' from bot_sys import config, log, aiogram_bot, bot_messages, bd_table, user_access, test_bot
from bot_modules import mod_agregator, start, profile, backup, groups, access, projects, tasks, needs, comments, languages, messages, buttons
bd_file_name = 'bot.db' bd_file_name = 'bot.db'
log_file_name = 'log.txt' log_file_name = 'log.txt'
default_language = 'ru'
g_Log = log.Log(log_file_name) g_Log = log.Log(log_file_name)
g_Bot = aiogram_bot.AiogramBot(config.GetTelegramBotApiToken(), bd_file_name, config.GetRootIDs(), g_Log) g_Bot = aiogram_bot.AiogramBot(config.GetTelegramBotApiToken(), bd_file_name, config.GetRootIDs(), g_Log)
default_language = 'ru'
g_BotMessages = bot_messages.BotMessages(default_language) g_BotMessages = bot_messages.BotMessages(default_language)
g_BotButtons = bot_messages.BotMessages(default_language) g_BotButtons = bot_messages.BotMessages(default_language)
g_BotSubscribes = bot_subscribes.BotSubscribes()
g_ModuleAgregator = mod_agregator.ModuleAgregator() g_ModuleAgregator = mod_agregator.ModuleAgregator()
@ -38,106 +30,58 @@ mod_projects_name = projects.module_name
mod_languages_name = languages.module_name mod_languages_name = languages.module_name
mod_messages_name = messages.module_name mod_messages_name = messages.module_name
mod_buttons_name = buttons.module_name mod_buttons_name = buttons.module_name
mod_users_name = users.module_name
mod_groups_name = groups.module_name
mod_user_in_groups_name = user_in_groups.module_name
mod_orders_cat_name = orders_cat.module_name
mod_orders_name = orders.module_name
mod_all_orders_name = all_orders.module_name
mod_user_message_name = user_message.module_name
start_mod_list = [mod_start_name] start_mod_list = [mod_start_name]
mod_access = access.ModuleAccess(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_access)
mod_users = users.ModuleUsers(None, None, start_mod_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_access = access.ModuleAccess(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_users) g_ModuleAgregator.AddModule(mod_access)
mod_user_message = user_message.ModuleUserMessage(mod_users_name, None, start_mod_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_user_message)
child_mod_name_list = [mod_start_name, mod_users_name, mod_user_in_groups_name] mod_groups = groups.ModuleGroups(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
mod_groups = groups.ModuleGroups(None, mod_user_in_groups_name, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_groups) g_ModuleAgregator.AddModule(mod_groups)
mod_user_in_groups = user_in_groups.ModuleUserInGroups(mod_groups_name, None, start_mod_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_profile = profile.ModuleProfile(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_user_in_groups)
child_mod_name_list = [mod_start_name, mod_users_name, mod_groups_name, mod_user_in_groups_name, mod_user_message_name]
mod_users_groups_agregator = users_groups_agregator.ModuleUsersGroupsAgregator(child_mod_name_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_users_groups_agregator)
mod_profile = profile.ModuleProfile(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_profile) g_ModuleAgregator.AddModule(mod_profile)
mod_backup = backup.ModuleBackup(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_backup = backup.ModuleBackup(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_backup) g_ModuleAgregator.AddModule(mod_backup)
child_mod_name_list = [mod_start_name, mod_tasks_name, mod_needs_name, mod_comments_name] start_mod_name_list = [mod_start_name, mod_tasks_name, mod_needs_name, mod_comments_name]
mod_project = projects.ModuleProjects(None, mod_tasks_name, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_project = projects.ModuleProjects(None, mod_tasks_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_project) g_ModuleAgregator.AddModule(mod_project)
child_mod_name_list = [mod_start_name]#, mod_projects_name, mod_needs_name, mod_comments_name] start_mod_name_list = [mod_start_name]#, mod_projects_name, mod_needs_name, mod_comments_name]
mod_tasks = tasks.ModuleTasks(mod_projects_name, mod_needs_name, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_tasks = tasks.ModuleTasks(mod_projects_name, mod_needs_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_tasks) g_ModuleAgregator.AddModule(mod_tasks)
child_mod_name_list = [mod_start_name]#, mod_projects_name, mod_tasks_name, mod_comments_name] start_mod_name_list = [mod_start_name]#, mod_projects_name, mod_tasks_name, mod_comments_name]
mod_needs= needs.ModuleNeeds(mod_tasks_name, mod_comments_name, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_needs= needs.ModuleNeeds(mod_tasks_name, mod_comments_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_needs) g_ModuleAgregator.AddModule(mod_needs)
child_mod_name_list = [mod_start_name]#, mod_projects_name, mod_tasks_name, mod_needs_name] start_mod_name_list = [mod_start_name]#, mod_projects_name, mod_tasks_name, mod_needs_name]
mod_comments= comments.ModuleComments(mod_needs_name, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_comments= comments.ModuleComments(mod_needs_name, None, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_comments) g_ModuleAgregator.AddModule(mod_comments)
child_mod_name_list = [mod_start_name, mod_messages_name, mod_buttons_name] start_mod_name_list = [mod_start_name, mod_messages_name, mod_buttons_name]
mod_languages = languages.ModuleLanguages(None, mod_messages_name, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_languages = languages.ModuleLanguages(None, mod_messages_name, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_languages) g_ModuleAgregator.AddModule(mod_languages)
child_mod_name_list = [mod_start_name] start_mod_name_list = [mod_start_name]
mod_messages = messages.ModuleMessages(mod_languages_name, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_messages = messages.ModuleMessages(mod_languages_name, None, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_messages) g_ModuleAgregator.AddModule(mod_messages)
child_mod_name_list = [mod_start_name] start_mod_name_list = [mod_start_name]
mod_buttons = buttons.ModuleButtons(mod_languages_name, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_buttons = buttons.ModuleButtons(mod_languages_name, None, start_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_buttons) g_ModuleAgregator.AddModule(mod_buttons)
child_mod_name_list = [mod_start_name] start_mod_name_list = [
mod_orders_cat = orders_cat.ModuleOrdersCat(None, mod_orders_name, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_orders_cat)
child_mod_name_list = [mod_start_name]
mod_orders = orders.ModuleUserOrders(mod_orders_cat_name, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_orders)
child_mod_name_list = [mod_start_name, mod_orders_cat_name]
mod_all_orders = all_orders.ModuleAllOrders(mod_orders_cat_name, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_all_orders)
child_mod_name_list = [mod_start_name]
mod_subscribe = subscribes.ModuleUserSubscribe(None, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_subscribe)
mod_bd_version = bd_version.ModuleBDVersion(g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_bd_version)
child_mod_name_list = [mod_start_name]
mod_authorize = authorize.ModuleAuthorize(None, None, child_mod_name_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_authorize)
child_mod_name_list = [
mod_profile.GetName(), mod_profile.GetName(),
mod_backup.GetName(), mod_backup.GetName(),
mod_users_groups_agregator.GetName(), mod_groups.GetName(),
mod_access.GetName(), mod_access.GetName(),
mod_project.GetName(), mod_project.GetName(),
mod_languages.GetName(), mod_languages.GetName(),
mod_orders.GetName(),
mod_all_orders.GetName(),
mod_subscribe.GetName(),
mod_bd_version.GetName(),
mod_authorize.GetName(),
] ]
mod_start = start.ModuleStart(child_mod_name_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log) mod_start = start.ModuleStart(start_mod_name_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_Log)
g_ModuleAgregator.AddModule(mod_start) g_ModuleAgregator.AddModule(mod_start)
# Первичная инициализация модулей. # Первичная инициализация модулей.
@ -164,13 +108,13 @@ for m in modules:
m.RegisterHandlers() m.RegisterHandlers()
# Юнит тесты модулей и файлов # Юнит тесты модулей и файлов
test_mods = [user_access, bd_table, bot_subscribes] test_mods = [user_access, bd_table] #, test_bot]
for m in test_mods: for m in test_mods:
m.Test() m.Test()
if __name__ == '__main__': if __name__ == '__main__':
#os.system('clear') # os.system('clear')
#os.system('cls') # os.system('cls')
g_Log.Success(log_start_message) g_Log.Success(log_start_message)
g_Bot.StartPolling() g_Bot.StartPolling()

22
manage.py

@ -1,22 +0,0 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanel.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

8
requirements.txt

@ -1,8 +1,2 @@
aiogram==2.20 aiogram==2.20
colorama==0.4.5 colorama==0.4.5
weasyprint
Django==2.2.1
python-dotenv==0.21.1
requests==2.31.0
urllib3==1.25.11

12
template/bd_item.py

@ -42,16 +42,6 @@ def GetKeyDataFromCallbackMessage(a_Message, a_Prefix):
key_item_id = str(a_Message.data).replace(a_Prefix, '') key_item_id = str(a_Message.data).replace(a_Prefix, '')
return key_item_id return key_item_id
def MixKeyboardFuncTemplate(a_Func1, a_Func2):
def KeyboardButtons(a_Message, a_UserGroups):
func = [a_Func1, a_Func2]
result = []
for f in func:
if f:
result += f(a_Message, a_UserGroups)
return result
return KeyboardButtons
def GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode): def GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode):
def GetCancelKeyboardButtons(a_Message, a_UserGroups): def GetCancelKeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [ cur_buttons = [
@ -100,7 +90,7 @@ def CheckAccessBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_KeyValue, a_WorkF
a_Bot.GetLog().Error(msg) a_Bot.GetLog().Error(msg)
return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(msg)), None return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(msg)), None
result_work_func = await a_WorkFunc(a_CallbackQuery, item[0], None, table_name = a_TableName) result_work_func = await a_WorkFunc(a_CallbackQuery, item[0])
if result_work_func is None or result_work_func.m_BotMessage is None: if result_work_func is None or result_work_func.m_BotMessage is None:
return result_work_func, result_work_func return result_work_func, result_work_func

34
template/bd_item_add.py

@ -10,9 +10,6 @@ from template import simple_message, bd_item_select, bd_item
cancel_message = ''' cancel_message = '''
🚫 Добавление отменено 🚫 Добавление отменено
''' '''
error_photo_type_message = '''
🚫 Неверный формат изображений
'''
def StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMStart, a_MessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD): def StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMStart, a_MessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD):
async def StartAddBDItem(a_CallbackQuery, state): async def StartAddBDItem(a_CallbackQuery, state):
@ -30,7 +27,7 @@ def StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMStart, a_MessageFunc, a_ParentTabl
if parent_id: if parent_id:
check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_CallbackQuery) check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_CallbackQuery)
else: else:
res_of_work_func = await a_MessageFunc(a_CallbackQuery, None, item_data) res_of_work_func = await a_MessageFunc(a_CallbackQuery, None)
if not check is None: if not check is None:
await state.finish() await state.finish()
@ -39,13 +36,13 @@ def StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMStart, a_MessageFunc, a_ParentTabl
return res_of_work_func return res_of_work_func
return simple_message.SimpleMessageTemplate(a_Bot, StartAddBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode) return simple_message.SimpleMessageTemplate(a_Bot, StartAddBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode)
def FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text): def FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text):
return FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, a_ButtonFunc, True, access_mode = access_mode, field_type = field_type) return FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_ButtonFunc, True, access_mode = access_mode, field_type = field_type)
def NextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text): def NextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text):
return FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, False, access_mode = access_mode, field_type = field_type) return FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, False, access_mode = access_mode, field_type = field_type)
def FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, a_Finish, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text): def FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, a_Finish, access_mode = user_access.AccessMode.ADD, field_type = bd_item.FieldType.text):
async def FinishAddBDItem(a_Message, state): async def FinishAddBDItem(a_Message, state):
state_func = None state_func = None
if a_Finish: if a_Finish:
@ -68,7 +65,7 @@ def FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableNa
if parent_id: if parent_id:
check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_Message) check, res_of_work_func = await bd_item.CheckAccessBDItemTemplate(a_Bot, a_ParentTableName, a_ParentKeyFieldName, parent_id, a_MessageFunc, access_mode)(a_Message)
else: else:
res_of_work_func = await a_MessageFunc(a_Message, None, item_data) res_of_work_func = await a_MessageFunc(a_Message, None)
if not check is None: if not check is None:
await state_func() await state_func()
@ -82,15 +79,12 @@ def FinishOrNextAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableNa
if a_Message.photo == None or len(a_Message.photo) == 0: if a_Message.photo == None or len(a_Message.photo) == 0:
await state.finish() await state.finish()
return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(error_photo_type_message), keyboard_func = a_FinishButtonFunc) return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(error_photo_type_message), keyboard_func = a_FinishButtonFunc)
field_value = a_Message.photo[-1].file_id field_value = a_Message.photo[0].file_id
else: else:
result = a_Message.text field_value = a_Message.text
if a_PostProcessFunc:
result = a_PostProcessFunc(result)
field_value = result
item_data[a_FieldName] = field_value item_data[a_FieldName] = field_value
if a_Finish: if a_Finish:
res, error = await a_AddBDItemFunc(item_data, user_id) res, error = a_AddBDItemFunc(item_data, user_id)
await state_func() await state_func()
if error: if error:
return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(error)) return simple_message.WorkFuncResult(bot_messages.MakeBotMessage(error))
@ -107,9 +101,9 @@ def AddBDItem3RegisterHandlers(a_Bot, a_StartCheckFunc, a_FSM, a_FSMName, a_FSMD
reg_func(StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMName, a_AddNameMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc) reg_func(StartAddBDItemTemplate(a_Bot, a_FSM, a_FSMName, a_AddNameMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc)
# TODO: Сделать возможность не указывать все поля. пусть a_FSMName и a_NameField например могут быть пустыми. Возможно лучше вообще передавать список полей и их fsm # TODO: Сделать возможность не указывать все поля. пусть a_FSMName и a_NameField например могут быть пустыми. Возможно лучше вообще передавать список полей и их fsm
a_Bot.RegisterMessageHandler(NextAddBDItemTemplate(a_Bot, a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_NameField, a_AddDescMessageFunc, None, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMName) a_Bot.RegisterMessageHandler(NextAddBDItemTemplate(a_Bot, a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_NameField, a_AddDescMessageFunc, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMName)
a_Bot.RegisterMessageHandler(NextAddBDItemTemplate(a_Bot, a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_DescField, a_AddPhotoMessageFunc, None, a_AccessFunc, keyboard_skip_and_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMDesc) a_Bot.RegisterMessageHandler(NextAddBDItemTemplate(a_Bot, a_FSM, None, a_ParentTableName, a_ParentKeyFieldName, a_DescField, a_AddPhotoMessageFunc, a_AccessFunc, keyboard_skip_and_cancel, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.text), state = a_FSMDesc)
a_Bot.RegisterMessageHandler(FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_PhotoField, a_FinishMessageFunc, None, a_AccessFunc, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.photo), content_types = ['photo', 'text'], state = a_FSMPhoto) a_Bot.RegisterMessageHandler(FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_PhotoField, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = bd_item.FieldType.photo), content_types = ['photo', 'text'], state = a_FSMPhoto)
def AddBDItem1RegisterHandlers(a_Bot, a_StartCheckFunc, a_FSM, a_AddBDItemFunc, a_AddMessageFunc, a_FinishMessageFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, a_FieldType, access_mode = user_access.AccessMode.ADD): def AddBDItem1RegisterHandlers(a_Bot, a_StartCheckFunc, a_FSM, a_AddBDItemFunc, a_AddMessageFunc, a_FinishMessageFunc, a_ParentPrefix, a_ParentTableName : str, a_ParentKeyFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, a_FieldType, access_mode = user_access.AccessMode.ADD):
keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode) keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode)
@ -117,7 +111,7 @@ def AddBDItem1RegisterHandlers(a_Bot, a_StartCheckFunc, a_FSM, a_AddBDItemFunc,
if a_ParentTableName: if a_ParentTableName:
reg_func = a_Bot.RegisterCallbackHandler reg_func = a_Bot.RegisterCallbackHandler
reg_func(StartAddBDItemTemplate(a_Bot, a_FSM, a_FSM.bd_item, a_AddMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc) reg_func(StartAddBDItemTemplate(a_Bot, a_FSM, a_FSM.bd_item, a_AddMessageFunc, a_ParentTableName, a_ParentKeyFieldName, a_ParentPrefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), a_StartCheckFunc)
finish_handler = FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_FinishMessageFunc, None, a_AccessFunc, a_ButtonFunc, access_mode, field_type = a_FieldType) finish_handler = FinishAddBDItemTemplate(a_Bot, a_FSM, a_AddBDItemFunc, a_ParentTableName, a_ParentKeyFieldName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, access_mode, field_type = a_FieldType)
if a_FieldType == bd_item.FieldType.photo: if a_FieldType == bd_item.FieldType.photo:
a_Bot.RegisterMessageHandler(finish_handler, content_types = ['photo', 'text'], state = a_FSM.bd_item) a_Bot.RegisterMessageHandler(finish_handler, content_types = ['photo', 'text'], state = a_FSM.bd_item)
else: else:

10
template/bd_item_delete.py

@ -29,6 +29,16 @@ def DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_P
return simple_message.SimpleMessageTemplate(a_Bot, DeleteBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode) return simple_message.SimpleMessageTemplate(a_Bot, DeleteBDItem, a_ButtonFunc, None, a_AccessFunc, access_mode)
def SelectAndDeleteBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_StartCheckFunc, a_TableName : str, a_KeyName, a_ParentIDFieldName,a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.DELETE):
reg_func = a_Bot.RegisterMessageHandler
if a_ParentIDFieldName:
reg_func = a_Bot.RegisterCallbackHandler
a_Prefix = bd_item.HashPrefix(f'delete_{a_TableName}_{a_KeyName}:')
sel_handler = bd_item_select.SelectDBItemTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode)
reg_func(sel_handler, a_StartCheckFunc)
a_Bot.RegisterCallbackHandler(DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix))
def DeleteBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_TableName : str, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.DELETE): def DeleteBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_TableName : str, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.DELETE):
a_Bot.RegisterCallbackHandler(DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix)) a_Bot.RegisterCallbackHandler(DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_PreDeleteWorkFunc, a_PostDeleteWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix))

39
template/bd_item_edit.py

@ -18,24 +18,8 @@ error_photo_type_message = '''
def StartEditBDItemTemplate(a_Bot, a_FSM, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.EDIT): def StartEditBDItemTemplate(a_Bot, a_FSM, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.EDIT):
return bd_item_add.StartAddBDItemTemplate(a_Bot, a_FSM, a_FSM.item_field, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = access_mode) return bd_item_add.StartAddBDItemTemplate(a_Bot, a_FSM, a_FSM.item_field, a_MessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, a_ButtonFunc, a_FinishButtonFunc, access_mode = access_mode)
def FinishEditBDItemTemplate(a_Bot, a_EditBDItemFunc, a_FSM, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text): def FinishEditBDItemTemplate(a_Bot, a_FSM, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text):
return bd_item_add.FinishAddBDItemTemplate(a_Bot, a_FSM, a_EditBDItemFunc, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_PostProcessFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, field_type = field_type) def EditBDItemFunc(a_ItemData, a_UserID):
def CustomEditBDItemRegisterHandlers(a_Bot, a_EditBDItemFunc, a_SelectSource, a_FSM, a_StartMessage, a_EditMessageFunc, a_FinishMessageFunc, a_TableName, a_KeyName, a_FieldName, a_PostProcessFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_AdditionalButtonFunc, a_FinishButtonFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text):
keyboard = bd_item.MixKeyboardFuncTemplate(a_AdditionalButtonFunc, bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode))
a_Prefix = bd_item_select.SelectRegisterHandlers(a_Bot, a_SelectSource, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode)
a_Bot.RegisterCallbackHandler(StartEditBDItemTemplate(a_Bot, a_FSM, a_EditMessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, keyboard, a_FinishButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix))
if field_type == bd_item.FieldType.photo:
a_Bot.RegisterMessageHandler(FinishEditBDItemTemplate(a_Bot, a_EditBDItemFunc, a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_PostProcessFunc, a_AccessFunc, a_FinishButtonFunc, access_mode, field_type = field_type), content_types = ['photo', 'text'], state = a_FSM.item_field)
else:
a_Bot.RegisterMessageHandler(FinishEditBDItemTemplate(a_Bot, a_EditBDItemFunc, a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_PostProcessFunc, a_AccessFunc, a_FinishButtonFunc, access_mode, field_type = field_type), state = a_FSM.item_field)
return a_Prefix
def EditBDItemRegisterHandlers(a_Bot, a_SelectSource, a_FSM, a_StartMessage, a_EditMessageFunc, a_FinishMessageFunc, a_TableName, a_KeyName, a_FieldName, a_PostProcessFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_AdditionalButtonFunc, a_FinishButtonFunc, a_OnChangeFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text):
async def EditBDItemFunc(a_ItemData, a_UserID):
item_id = a_ItemData[a_KeyName] item_id = a_ItemData[a_KeyName]
field_value = a_ItemData[a_FieldName] field_value = a_ItemData[a_FieldName]
res, error = bd_item.EditBDItemInTableTemplate(a_Bot, a_TableName, a_KeyName, a_FieldName)(item_id, field_value) res, error = bd_item.EditBDItemInTableTemplate(a_Bot, a_TableName, a_KeyName, a_FieldName)(item_id, field_value)
@ -44,7 +28,22 @@ def EditBDItemRegisterHandlers(a_Bot, a_SelectSource, a_FSM, a_StartMessage, a_E
else: else:
a_Bot.GetLog().Success(f'Пользователь {a_UserID} изменил поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}.') a_Bot.GetLog().Success(f'Пользователь {a_UserID} изменил поле в таблице {a_TableName} ключу {a_KeyName}={item_id}. Новое значение поля {a_FieldName}={field_value}.')
await a_OnChangeFunc(item_id, a_ItemData, a_UserID) a_OnChangeFunc()
return res, error return res, error
return CustomEditBDItemRegisterHandlers(a_Bot, EditBDItemFunc, a_SelectSource, a_FSM, a_StartMessage, a_EditMessageFunc, a_FinishMessageFunc, a_TableName, a_KeyName, a_FieldName, a_PostProcessFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_AdditionalButtonFunc, a_FinishButtonFunc, access_mode = access_mode, field_type = field_type) return bd_item_add.FinishAddBDItemTemplate(a_Bot, a_FSM, EditBDItemFunc, a_TableName, a_KeyName, a_FieldName, a_MessageFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, field_type = field_type)
def EditBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_FSM, a_StartCheckFunc, a_StartMessage, a_EditMessageFunc, a_FinishMessageFunc, a_TableName : str, a_KeyName, a_ParentIDFieldName, a_FieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode = user_access.AccessMode.EDIT, field_type = bd_item.FieldType.text):
reg_func = a_Bot.RegisterMessageHandler
if a_ParentIDFieldName:
reg_func = a_Bot.RegisterCallbackHandler
keyboard_cancel = bd_item.GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, access_mode)
a_Prefix = bd_item.HashPrefix(f'edit_{a_TableName}_{a_KeyName}_{a_FieldName}:')
sel_handler = bd_item_select.SelectDBItemTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode)
reg_func(sel_handler, a_StartCheckFunc)
a_Bot.RegisterCallbackHandler(StartEditBDItemTemplate(a_Bot, a_FSM, a_EditMessageFunc, a_TableName, a_KeyName, a_Prefix, a_AccessFunc, keyboard_cancel, a_ButtonFunc, access_mode), bd_item.GetCheckForPrefixFunc(a_Prefix))
if field_type == bd_item.FieldType.photo:
a_Bot.RegisterMessageHandler(FinishEditBDItemTemplate(a_Bot, a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode, field_type = field_type), content_types = ['photo', 'text'], state = a_FSM.item_field)
else:
a_Bot.RegisterMessageHandler(FinishEditBDItemTemplate(a_Bot, a_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_AccessFunc, a_ButtonFunc, a_OnChangeFunc, access_mode, field_type = field_type), state = a_FSM.item_field)

89
template/bd_item_select.py

@ -7,12 +7,14 @@ from bot_sys import user_access, bot_bd, keyboard
from bot_modules import access_utils, groups_utils from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item from template import simple_message, bd_item
from abc import ABC, abstractmethod def GetBDItemsListKeyboardButtonsTemplate(a_Bot, a_TableName : str, a_ParentIDFieldName, a_PrevPrefix, a_NextPrefix : str, a_GetButtonNameAndKeyValueAndAccessFunc, access_mode = user_access.AccessMode.VIEW):
def GetCustomListKeyboardButtonsTemplate(a_Bot, a_GetItemsFunc, a_PrevPrefix, a_NextPrefix : str, a_GetButtonNameAndKeyValueAndAccessFunc, access_mode = user_access.AccessMode.VIEW):
def GetBDItemsListKeyboardButtons(a_Message, a_UserGroups): def GetBDItemsListKeyboardButtons(a_Message, a_UserGroups):
parent_id = bd_item.GetKeyDataFromCallbackMessage(a_Message, a_PrevPrefix) parent_id = bd_item.GetKeyDataFromCallbackMessage(a_Message, a_PrevPrefix)
items = a_GetItemsFunc(a_Message, a_UserGroups, parent_id) items = []
if a_ParentIDFieldName and parent_id and parent_id != '':
items = bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_ParentIDFieldName)(parent_id)
else:
items = bd_item.GetAllItemsTemplate(a_Bot, a_TableName)()
items_button_list = [] items_button_list = []
for t in items: for t in items:
@ -25,78 +27,23 @@ def GetCustomListKeyboardButtonsTemplate(a_Bot, a_GetItemsFunc, a_PrevPrefix, a_
return keyboard.MakeInlineKeyboardButtons(a_Bot, items_button_list, a_UserGroups) return keyboard.MakeInlineKeyboardButtons(a_Bot, items_button_list, a_UserGroups)
return GetBDItemsListKeyboardButtons return GetBDItemsListKeyboardButtons
def GetBDItemsTemplate(a_Bot, a_TableName : str, a_ParentIDFieldName): def SelectDBItemTemplate(a_Bot, a_TableName : str, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_NextPrefix, access_mode = user_access.AccessMode.VIEW):
def GetBDItems(a_Message, a_UserGroups, a_ParentID): inline_keyboard_func = GetBDItemsListKeyboardButtonsTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_NextPrefix, a_GetButtonNameAndKeyValueAndAccessFunc)
items = []
if a_ParentIDFieldName and a_ParentID and a_ParentID != '':
items = bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_ParentIDFieldName)(a_ParentID)
else:
items = bd_item.GetAllItemsTemplate(a_Bot, a_TableName)()
return items
return GetBDItems
def SelectCustomTemplate(a_Bot, a_GetItemsFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_NextPrefix, access_mode = user_access.AccessMode.VIEW):
inline_keyboard_func = GetCustomListKeyboardButtonsTemplate(a_Bot, a_GetItemsFunc, a_PrevPrefix, a_NextPrefix, a_GetButtonNameAndKeyValueAndAccessFunc)
return simple_message.InfoMessageTemplate(a_Bot, a_StartMessage, None, inline_keyboard_func, a_AccessFunc, access_mode) return simple_message.InfoMessageTemplate(a_Bot, a_StartMessage, None, inline_keyboard_func, a_AccessFunc, access_mode)
class ISelectSource(ABC): def FirstSelectBDItemRegisterHandlers(a_Bot, a_PrefixBase, a_ButtonName, a_TableName : str, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
@abstractmethod
def IsFirst(self):
pass
@abstractmethod
def GetItemsFunc(self):
pass
@abstractmethod
def GetCheckFunc(self):
pass
@abstractmethod
def GetPrevPrefix(self):
pass
@abstractmethod
def GetPrefixBase(self):
pass
class DBItemSelectSource(ISelectSource):
def __init__(self, a_Bot, a_TableName, a_ParentIDFieldName, a_PrevPrefix, a_ButtonName):
self.m_Bot = a_Bot
self.m_TableName = a_TableName
self.m_ParentIDFieldName = a_ParentIDFieldName
self.m_PrevPrefix = a_PrevPrefix
self.m_ButtonName = a_ButtonName
def IsFirst(self):
return not self.m_ParentIDFieldName
def GetItemsFunc(self):
return GetBDItemsTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName)
def GetCheckFunc(self):
if self.IsFirst():
return bd_item.GetCheckForTextFunc(self.m_ButtonName)
return bd_item.GetCheckForPrefixFunc(self.m_PrevPrefix)
def GetPrevPrefix(self):
return self.m_PrevPrefix
def GetPrefixBase(self): a_Prefix = bd_item.HashPrefix(f'first_select_{a_TableName}_{a_KeyName}_in_base_{a_PrefixBase}:')
if self.m_PrevPrefix:
return self.m_PrevPrefix
return self.m_ButtonName
def SelectRegisterHandlers(a_Bot, a_SelectSource, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW): sel_handler = SelectDBItemTemplate(a_Bot, a_TableName, None, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, None, a_Prefix, access_mode = access_mode)
reg_func = a_Bot.RegisterMessageHandler a_Bot.RegisterMessageHandler(sel_handler, bd_item.GetCheckForTextFunc(a_ButtonName))
if not a_SelectSource.IsFirst():
reg_func = a_Bot.RegisterCallbackHandler
a_NextPrefix = bd_item.HashPrefix(f'select_{a_SelectSource}_after_prefix_or_in_base_{a_SelectSource.GetPrefixBase()}:') return a_Prefix
sel_handler = SelectCustomTemplate(a_Bot, a_SelectSource.GetItemsFunc(), a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_SelectSource.GetPrevPrefix(), a_NextPrefix, access_mode = access_mode) def NextSelectBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_ParentIDFieldName, a_TableName : str, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = user_access.AccessMode.VIEW):
reg_func(sel_handler, a_SelectSource.GetCheckFunc()) a_Prefix = bd_item.HashPrefix(f'next_select_{a_TableName}_{a_KeyName}_{a_ParentIDFieldName}_after_prefix_{a_PrevPrefix}:')
return a_NextPrefix sel_handler = SelectDBItemTemplate(a_Bot, a_TableName, a_ParentIDFieldName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_PrevPrefix, a_Prefix, access_mode = access_mode)
a_Bot.RegisterCallbackHandler(sel_handler, bd_item.GetCheckForPrefixFunc(a_PrevPrefix))
return a_Prefix

10
template/bd_item_view.py

@ -5,10 +5,18 @@
from bot_sys import user_access, bot_bd, keyboard from bot_sys import user_access, bot_bd, keyboard
from bot_modules import access_utils, groups_utils from bot_modules import access_utils, groups_utils
from template import simple_message, bd_item_delete, bd_item from template import simple_message, bd_item_select, bd_item_delete, bd_item
def ShowBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_WorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW): def ShowBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_WorkFunc, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
return bd_item_delete.DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_WorkFunc, None, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, delete = False) return bd_item_delete.DeleteBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_WorkFunc, None, a_Prefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, delete = False)
def ShowBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW): def ShowBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
a_Bot.RegisterCallbackHandler(ShowBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix)) a_Bot.RegisterCallbackHandler(ShowBDItemTemplate(a_Bot, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_PrevPrefix, a_AccessFunc, a_ButtonFunc, access_mode = access_mode), bd_item.GetCheckForPrefixFunc(a_PrevPrefix))
def FirstSelectAndShowBDItemRegisterHandlers(a_Bot, a_ButtonName, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
a_Prefix = bd_item_select.FirstSelectBDItemRegisterHandlers(a_Bot, '', a_ButtonName, a_TableName, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode)
ShowBDItemRegisterHandlers(a_Bot, a_Prefix, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode)
def LastSelectAndShowBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_ParentIDFieldName, a_TableName : str, a_KeyName, a_ShowItemWorkFunc, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, a_ButtonFunc, access_mode = user_access.AccessMode.VIEW):
a_Prefix = bd_item_select.NextSelectBDItemRegisterHandlers(a_Bot, a_PrevPrefix, a_ParentIDFieldName, a_TableName, a_KeyName, a_GetButtonNameAndKeyValueAndAccessFunc, a_StartMessage, a_AccessFunc, access_mode = access_mode)
ShowBDItemRegisterHandlers(a_Bot, a_Prefix, a_TableName, a_KeyName, a_ShowItemWorkFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode)

93
template/docs_message.py

@ -1,93 +0,0 @@
# -*- coding: utf8 -*-
# Общественное достояние 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Сообщения для работы с документами
from bot_sys import log, config, user_access
from bot_modules import groups_utils
from template import simple_message
#import odf
def DocFilesTemplate(a_Bot, a_FilesFunc, a_CaptionMessage, a_AccessFunc, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_ErrorMessage, access_mode = user_access.AccessMode.EDIT):
async def DocFiles(a_Message):
user_id = str(a_Message.from_user.id)
user_groups= groups_utils.GetUserGroupData(a_Bot, user_id)
if not user_access.CheckAccess(a_Bot.GetRootIDs(), a_AccessFunc(), user_groups, access_mode):
return await simple_message.AccessDeniedMessage(a_Bot, a_GetButtonsFunc, user_id, a_Message, user_groups)
msg = a_CaptionMessage.GetDesc()
msg = msg.replace('@time', a_Bot.GetLog().GetTime())
files = a_FilesFunc(user_id)
if not files:
await simple_message.SendMessage(a_Bot, a_ErrorMessage, a_GetButtonsFunc, None, user_id, a_Message, user_groups)
return
for file_path, dict_replace in files.items():
if not dict_replace:
continue
new_file = await MakeDocFile(a_Bot, file_path, dict_replace, user_id)
document = await GetFile(a_Bot, new_file)
if document is None:
await simple_message.SendMessage(a_Bot, a_ErrorMessage, a_GetButtonsFunc, None, user_id, a_Message, user_groups)
else:
await a_Bot.SendDocument(
user_id,
document,
msg,
simple_message.ProxyGetButtonsTemplate(a_GetButtonsFunc)(a_Message, user_groups),
simple_message.ProxyGetButtonsTemplate(a_GetInlineButtonsFunc)(a_Message, user_groups)
)
return DocFiles
async def ReplaceInFile(a_Bot, a_InputFileName, a_OutFileName, a_DictReplace):
try:
filedata = ''
with open(a_InputFileName, 'r') as in_f:
filedata = in_f.read()
s = filedata
for rep_this, to_this in a_DictReplace.items():
s = s.replace(rep_this, to_this)
with open(a_OutFileName, 'w') as out_f:
out_f.write(s)
a_Bot.GetLog().Success(f'Создан файл {a_OutFileName}')
return a_OutFileName
except Exception as e:
a_Bot.GetLog().Error(f'Не удалось заменить текст в фале {a_InputFileName} и записать в {a_OutFileName}. Ошибка {str(e)}')
return None
from weasyprint import HTML, CSS
async def SaveAsPdf(a_Bot, a_InputFileName, a_OutFileName):
try:
HTML(filename = a_InputFileName).write_pdf(a_OutFileName)
a_Bot.GetLog().Success(f'Создан файл {a_OutFileName}')
return a_OutFileName
except Exception as e:
a_Bot.GetLog().Error(f'Не удалось создать пдф из фала {a_InputFileName} и записать в {a_OutFileName}. Ошибка {str(e)}')
return None
async def MakeDocFile(a_Bot, a_FilePath, a_DictReplace, a_user_id):
user_file_path = a_FilePath[:-5]
pdf_file_path = user_file_path
user_file_path += f"_{a_user_id}.html"
pdf_file_path += f"_{a_user_id}.pdf"
user_file_path = await ReplaceInFile(a_Bot, a_FilePath, user_file_path, a_DictReplace)
if not user_file_path:
return None
return await SaveAsPdf(a_Bot, user_file_path, pdf_file_path)
async def GetFile(a_Bot, a_Path):
if not a_Path:
return None
try:
document = open(a_Path, 'rb')
a_Bot.GetLog().Success(f'Загружен файл {a_Path}')
return document
except Exception as e:
a_Bot.GetLog().Error(f'Не удалось загрузить файл {a_Path}. Ошибка {str(e)}')
return None

2
template/file_message.py

@ -16,7 +16,7 @@ def BackupFileTemplate(a_Bot, a_Path, a_CaptionMessage, a_AccessFunc, a_GetButto
document = await GetFile(a_Bot, a_Path) document = await GetFile(a_Bot, a_Path)
if document is None: if document is None:
return await simple_message.SendMessage(a_Bot, a_ErrorMessage, a_GetButtonsFunc, None, user_id, a_Message, user_groups) return simple_message.SendMessage(a_Bot, a_ErrorMessage, a_GetButtonsFunc, None, user_id, a_Message, user_groups)
msg = a_CaptionMessage.GetDesc() msg = a_CaptionMessage.GetDesc()
msg = msg.replace('@time', a_Bot.GetLog().GetTime()) msg = msg.replace('@time', a_Bot.GetLog().GetTime())

4
template/simple_message.py

@ -3,7 +3,7 @@
# Простые информационные сообщения # Простые информационные сообщения
from bot_sys import user_access, bot_messages from bot_sys import user_access
from bot_modules import access_utils, groups_utils from bot_modules import access_utils, groups_utils
from aiogram import types from aiogram import types
@ -53,8 +53,6 @@ def SimpleMessageTemplate(a_Bot, a_WorkFunc, a_GetButtonsFunc, a_GetInlineButton
if res is None: if res is None:
return return
user_groups = groups_utils.GetUserGroupData(a_Bot, user_id) # При самом первом запуске a_WorkFunc добавляет пользователя
Inline_keyboard_func = a_GetInlineButtonsFunc Inline_keyboard_func = a_GetInlineButtonsFunc
if res.Inline_keyboard_func: if res.Inline_keyboard_func:
Inline_keyboard_func = res.Inline_keyboard_func Inline_keyboard_func = res.Inline_keyboard_func

4
template/sql_request.py

@ -3,7 +3,7 @@
# Сообщения для работы с sql запросами # Сообщения для работы с sql запросами
from bot_sys import user_access, keyboard, bot_messages, interfaces from bot_sys import user_access, keyboard, bot_messages
from bot_modules import groups_utils from bot_modules import groups_utils
from template import bd_item, simple_message from template import bd_item, simple_message
@ -31,7 +31,7 @@ def RequestToBDTemplate(a_Bot, a_StartMessage, a_GetButtonsFunc, a_AccessFunc, a
await a_FSM.sqlRequest.set() await a_FSM.sqlRequest.set()
print ('a_FSM.sqlRequest.set()', a_StartMessage) print ('a_FSM.sqlRequest.set()', a_StartMessage)
await simple_message.SendMessage(a_Bot, a_StartMessage, GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode), None, user_id, a_Message, user_groups, parse_mode=interfaces.ParseMode.Markdown.value) await simple_message.SendMessage(a_Bot, a_StartMessage, GetCancelKeyboardButtonsTemplate(a_Bot, a_AccessFunc, a_AccessMode), None, user_id, a_Message, user_groups, parse_mode='Markdown')
return RequestToBDStart return RequestToBDStart
def RequestToBDFinishTemplate(a_Bot, a_GetButtonsFunc, a_AccessFunc, a_AccessMode): def RequestToBDFinishTemplate(a_Bot, a_GetButtonsFunc, a_AccessFunc, a_AccessMode):

Loading…
Cancel
Save