Compare commits

..

4 Commits

  1. 7
      .gitignore
  2. 40
      README.md
  3. 0
      __init__.py
  4. 0
      adminpanel/__init__.py
  5. 131
      adminpanel/admin.py
  6. 5
      adminpanel/apps.py
  7. 23
      adminpanel/config.py
  8. 44
      adminpanel/models.py
  9. 0
      adminpanel/templates/__init__.py
  10. 6
      adminpanel/templates/send_telegram_message.html
  11. 0
      adminpanel/tests.py
  12. 10
      adminpanel/urls.py
  13. 9
      adminpanel/views.py
  14. 15
      adminpanel/wsgi.py
  15. 0
      adminpanelapp/__init__.py
  16. 40
      adminpanelapp/admin.py
  17. 19
      adminpanelapp/adminpanel/models.py
  18. 0
      adminpanelapp/adminpanel/templates/__init__.py
  19. 3
      adminpanelapp/adminpanel/tests.py
  20. 0
      adminpanelapp/adminpanel/urls.py
  21. 20
      adminpanelapp/adminpanel/views.py
  22. 0
      adminpanelapp/adminpanelapp/__init__.py
  23. 6
      adminpanelapp/adminpanelapp/asgi.py
  24. 128
      adminpanelapp/adminpanelapp/settings.py
  25. 28
      adminpanelapp/adminpanelapp/urls.py
  26. 16
      adminpanelapp/adminpanelapp/wsgi.py
  27. 16
      adminpanelapp/asgi.py
  28. 0
      adminpanelapp/db.sqlite3
  29. 22
      adminpanelapp/manage.py
  30. 142
      adminpanelapp/models.py
  31. 33
      adminpanelapp/settings.py
  32. 8
      adminpanelapp/templates/send_telegram_message.html
  33. 15
      adminpanelapp/urls.py
  34. 16
      adminpanelapp/wsgi.py
  35. 120
      auth_docs/test_doc.html
  36. BIN
      auth_docs/test_doc.odt
  37. 2
      bot_modules/access.py
  38. 244
      bot_modules/all_orders.py
  39. 397
      bot_modules/authorize.py
  40. 2
      bot_modules/backup.py
  41. 51
      bot_modules/bd_version.py
  42. 2
      bot_modules/buttons.py
  43. 7
      bot_modules/comments.py
  44. 4
      bot_modules/groups.py
  45. 6
      bot_modules/groups_utils.py
  46. 2
      bot_modules/languages.py
  47. 35
      bot_modules/messages.py
  48. 18
      bot_modules/mod_simple_message.py
  49. 455
      bot_modules/mod_table_operate.py
  50. 7
      bot_modules/needs.py
  51. 118
      bot_modules/orders.py
  52. 138
      bot_modules/orders_cat.py
  53. 2
      bot_modules/profile.py
  54. 7
      bot_modules/projects.py
  55. 2
      bot_modules/start.py
  56. 30
      bot_modules/subscribes.py
  57. 7
      bot_modules/tasks.py
  58. 2
      bot_modules/user_in_groups.py
  59. 143
      bot_modules/user_message.py
  60. 15
      bot_modules/users.py
  61. 11
      bot_modules/users_groups_agregator.py
  62. 9
      bot_sys/aiogram_bot.py
  63. 28
      bot_sys/bd_table.py
  64. 2
      bot_sys/bot_bd.py
  65. 42
      bot_sys/bot_messages.py
  66. 23
      bot_sys/bot_subscribes.py
  67. 14
      bot_sys/config.py
  68. 8
      bot_sys/interfaces.py
  69. 4
      bot_sys/user_access.py
  70. 1
      config_auth_docs
  71. 30
      main.py
  72. 2
      manage.py
  73. 9
      requirements.txt
  74. 2
      template/bd_item.py
  75. 6
      template/bd_item_add.py
  76. 31
      template/bd_item_edit.py
  77. 93
      template/docs_message.py
  78. 2
      template/file_message.py
  79. 2
      template/simple_message.py
  80. 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/

40
README.md

@ -1,4 +1,4 @@
# TPlatformBot ## TPlatformBot
### Видеоинструкции ### Видеоинструкции
@ -8,12 +8,6 @@
Обзор возможностей пользователя - https://vk.com/video-210998646_456239042 Обзор возможностей пользователя - 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-бот с возможностью редактирования прав доступа, как пользователям, так и группам пользователей
Список модулей Список модулей
@ -73,27 +67,17 @@
Тестовая версия запущена по ссылке Тестовая версия запущена по ссылке
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 1. Необходимо установить пакет Django
2. Создайте суперпользователя pip install requirements.txt
2. Добавляем информацию в базу данных
python manage.py makemigrations
python manage.py migrate
3. Создаем суперпользователя, чтобы зайти в админку
python manage.py createsuperuser python manage.py createsuperuser
3. Введите имя пользователя, почту и пароль Придумываем логин, почту и пароль
4. Запустите сервер 4. Запускаем приложение
python manage.py runserver. Можно запустить с параметром IP:PORT, например 127.0.0.1:8080 python manage.py runserver
5. Перейдите по адерсу http://127.0.0.1:8000/ (адрес выведется в терминале) и введите данные ранее созданного пользователя и пароль 5. Переходим по ссылке http://127.0.0.1:8000/admin/ и вводим логин, пароль

0
__init__.py

0
adminpanel/__init__.py

131
adminpanel/admin.py

@ -0,0 +1,131 @@
import requests
from django.http import HttpResponseRedirect
from django.utils.html import format_html
from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME
from adminpanelapp.settings import g_telegram_bot_api_token
from .models import Orders
from django.contrib import admin, messages
from django.urls import reverse
class OrdersAdmin(admin.ModelAdmin):
list_display = ('name', 'description', 'time_create', 'adress', 'is_approved', 'orders_photo', 'cheque_image')
list_editable = ('is_approved',)
# exclude = ('param_id', 'send_message')
actions =['change_value_and_redirect',]
readonly_fields = ['order_photo', 'cheque']
def orders_photo(self, obj):
if obj.order_photo and obj.order_photo.url:
return format_html('<img src="{}" width="100" height="100" />', obj.order_photo.url)
return "-"
def cheque_image(self, obj):
if obj.cheque and obj.cheque.url:
return format_html('<img src="{}" width="100" height="100" />', obj.cheque.url)
return "-"
# image_tag.short_description = 'Cheque'
# def photo_link(self, obj):
# url = obj.get_absolute_url()
# return format_html('<a href="{}">{}</a>', url, obj.photo_link)
#
# photo_link.short_description = 'photo_link'
# def change_view(self, request, object_id, form_url='', extra_context=None):
# obj = self.get_object(request, object_id)
# extra_context = extra_context or {}
# extra_context['chat_id'] = obj.param_id
#
# if obj.send_message:
# obj.send_message = False
# obj.save()
# url = reverse('send_telegram_message')
# chat_id = obj.param_id
# url = f"{url}?param_id={chat_id}"
# print(chat_id)
# return HttpResponseRedirect(url)
#
#
# return super().change_view(request, object_id, form_url, extra_context)
# def change_view(self, request, object_id, form_url='', extra_context=None):
# obj = self.get_object(request, object_id)
# if obj.send_message:
# url = reverse('send_telegram_message')
#
# return HttpResponseRedirect(url)
#
# return super().change_view(request, object_id, form_url, extra_context)
# def change_value_and_redirect(modeladmin, request, queryset):
#
# # Получаем список выбранных объектов
# selected_objects = request.POST.getlist(ACTION_CHECKBOX_NAME)
# # Проверяем, что выбран только один объект
# if len(selected_objects) != 1:
# # Если выбрано несколько объектов или не выбран ни один, выбрасываем исключение или выводим сообщение пользователю
# raise ValueError("Выберите только один объект")
# # Получаем ID выбранного объекта
# selected_object_id = int(selected_objects[0])
# # Получаем объект по ID
# obj = queryset.get(id=selected_object_id)
# # Изменяем значение ячейки объекта на False
# obj.send_message = True
# obj.save()
# # Редирект на страницу send_tg_message
# url = reverse('send_telegram_message')
# return HttpResponseRedirect(url)
def change_value_and_redirect(modeladmin, request, queryset):
selected_objects = request.POST.getlist(ACTION_CHECKBOX_NAME)
if len(selected_objects) != 1:
messages.error(request, "Выберите только один объект")
return
selected_chat_id = int(selected_objects[0])
obj = queryset.get(id=selected_chat_id)
chat_id = obj.param_id
url = reverse('send_telegram_message', kwargs={'chat_id': chat_id})
return HttpResponseRedirect(url)
change_value_and_redirect.short_description = 'Отправка сообщения'
def save_model(self, request, obj, form, change):
super().save_model(request, obj, form, change)
def send_telegram_message(message):
bot_token = g_telegram_bot_api_token
chat_id = obj.param_id
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
params = {
'chat_id': chat_id,
'text': message
}
response = requests.get(url, params=params)
if response.status_code == 200:
print("Сообщение успешно отправлено!")
else:
print("Ошибка при отправке сообщения")
if obj.is_approved == True:
message2 = 'Ваш заказ принят. Ожидайте получения'
send_telegram_message(message2)
admin.site.register(Orders, OrdersAdmin,)

5
adminpanelapp/apps.py → adminpanel/apps.py

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

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

44
adminpanel/models.py

@ -0,0 +1,44 @@
from django.db import models
import asyncio
class Orders(models.Model):
SEND_MESSAGE = (
(True, 'Написать'),
(False, 'Не отправлять'),
(None, 'Неизвестно'),
)
IS_APPROVED = (
(True, 'Заказ подтвержден'),
(False, 'Заказ не подтвержден'),
(None, 'Неизвестно'),
)
param_id = models.CharField(max_length=100, verbose_name='id пользователя в tg', null=True)
name = models.CharField(max_length=100, verbose_name='наименование', null=True)
description = models.TextField(verbose_name='описание', null=True)
order_photo = models.ImageField(upload_to='photo/')
cheque = models.ImageField(upload_to='photo/')
adress = models.CharField(max_length=100, verbose_name='адрес доставки', blank=True, null=True)
time_create = models.DateTimeField(auto_now_add=True, null=True)
# message = models.CharField(max_length=100, verbose_name='сообщение для пользователя', blank=True, null=True)
# send_message = models.BooleanField(default=False, verbose_name='отправить сообщение', null=True, choices=SEND_MESSAGE)
is_approved = models.BooleanField(default=False, verbose_name='подтверждение заказа', null=True, choices=IS_APPROVED)
class Meta:
app_label = 'adminpanel'
verbose_name_plural = 'Заказы'
def __str__(self):
return self.name

0
adminpanel/templates/__init__.py

6
adminpanel/templates/send_telegram_message.html

@ -0,0 +1,6 @@
<form method="post">
{% csrf_token %}
<label for="message">Сообщение:</label>
<input type="text" id="message" name="message">
<button type="submit">Отправить сообщение</button>
</form>

0
adminpanelapp/tests.py → adminpanel/tests.py

10
adminpanel/urls.py

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

9
adminpanelapp/views.py → adminpanel/views.py

@ -1,15 +1,18 @@
from django.contrib import messages from django.contrib import messages
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render, HttpResponse
import requests import requests
from django.urls import reverse from django.urls import reverse
from django.shortcuts import render
from bot_sys.config import GetTelegramBotApiToken from adminpanel.models import Orders
from bot_sys.config import g_telegram_bot_api_token
def send_telegram_message(request, chat_id): def send_telegram_message(request, chat_id):
if request.method == 'POST': if request.method == 'POST':
message = request.POST.get('message') message = request.POST.get('message')
bot_token = GetTelegramBotApiToken() bot_token = g_telegram_bot_api_token
url = f'https://api.telegram.org/bot{bot_token}/sendMessage?text={message}&chat_id={chat_id}' url = f'https://api.telegram.org/bot{bot_token}/sendMessage?text={message}&chat_id={chat_id}'
response = requests.get(url) response = requests.get(url)

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()

0
adminpanelapp/__init__.py

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)

19
adminpanelapp/adminpanel/models.py

@ -0,0 +1,19 @@
from django.db import models
class Orders(models.Model):
name = models.CharField(max_length=100, verbose_name='наименование', null=True)
description = models.TextField(verbose_name='описание', null=True)
time_create = models.DateTimeField(auto_now_add=True, null=True)
class Meta:
app_label = 'adminpanel'
verbose_name_plural = 'Заказы'
def __str__(self):
return self.name

0
adminpanelapp/adminpanel/templates/__init__.py

3
adminpanelapp/adminpanel/tests.py

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

0
adminpanelapp/adminpanel/urls.py

20
adminpanelapp/adminpanel/views.py

@ -0,0 +1,20 @@
import telegram
from django.http import HttpResponse
from django.shortcuts import render
def send_message(request):
if request.method == 'POST':
# Получение данных из POST-запроса
chat_id = request.POST.get('chat_id')
message_text = request.POST.get('message_text')
# Создание объекта Telegram Bot
bot = telegram.Bot(token='YOUR_TELEGRAM_BOT_TOKEN')
# Отправка сообщения
bot.send_message(chat_id=chat_id, text=message_text)
# Возвращение ответа
return HttpResponse('Message sent to Telegram.')
else:
return render(request, 'send_message.html')

0
adminpanelapp/adminpanelapp/__init__.py

6
adminpanel/asgi.py → adminpanelapp/adminpanelapp/asgi.py

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

128
adminpanelapp/adminpanelapp/settings.py

@ -0,0 +1,128 @@
"""
Django settings for adminpanelapp 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/
"""
from pathlib import Path
# 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!
SECRET_KEY = 'django-insecure-11*zwyl6y4w%2j(spzw)+0o8u@frpy++3xk+zoy(!5gg3$1wuf'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'adminpanel',
]
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 = 'adminpanelapp.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 = 'adminpanelapp.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# 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 = 'en-us'
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'
bot_token = '6212211018:AAEwcEN0NdjbhqDiClUk8vZkE_vfRUxsReU'

28
adminpanelapp/adminpanelapp/urls.py

@ -0,0 +1,28 @@
"""adminpanelapp URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path
urlpatterns = [
path('admin/', admin.site.urls),
path('send_message/', views.send_message, name='send_message'),
]

16
adminpanelapp/adminpanelapp/wsgi.py

@ -0,0 +1,16 @@
"""
WSGI config for adminpanelapp 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.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanelapp.settings')
application = get_wsgi_application()

16
adminpanelapp/asgi.py

@ -0,0 +1,16 @@
"""
ASGI config for adminpanelapp 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.1/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanelapp.settings')
application = get_asgi_application()

0
adminpanelapp/db.sqlite3

22
adminpanelapp/manage.py

@ -0,0 +1,22 @@
#!/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', 'adminpanelapp.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()

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'

33
adminpanel/settings.py → adminpanelapp/settings.py

@ -1,5 +1,5 @@
""" """
Django settings for adminpanel project. Django settings for adminpanelapp project.
Generated by 'django-admin startproject' using Django 4.1.4. Generated by 'django-admin startproject' using Django 4.1.4.
@ -11,22 +11,22 @@ https://docs.djangoproject.com/en/4.1/ref/settings/
""" """
import os import os
from pathlib import Path from pathlib import Path
from dotenv import load_dotenv
# Build paths inside the project like this: BASE_DIR / 'subdir'. # Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production # Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/ # See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret! # SECURITY WARNING: keep the secret key used in production secret!
load_dotenv() SECRET_KEY = 'django-insecure-11*zwyl6y4w%2j(spzw)+0o8u@frpy++3xk+zoy(!5gg3$1wuf'
SECRET_KEY = os.getenv('PLATFORM_ADMINPANEL_SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False DEBUG = True
ALLOWED_HOSTS = []
ALLOWED_HOSTS = ['*']
# Application definition # Application definition
@ -37,7 +37,8 @@ INSTALLED_APPS = [
'django.contrib.sessions', 'django.contrib.sessions',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'adminpanelapp', 'adminpanel',
] ]
@ -51,7 +52,7 @@ MIDDLEWARE = [
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
] ]
ROOT_URLCONF = 'adminpanel.urls' ROOT_URLCONF = 'adminpanelapp.urls'
TEMPLATES = [ TEMPLATES = [
{ {
@ -69,16 +70,16 @@ TEMPLATES = [
}, },
] ]
WSGI_APPLICATION = 'adminpanel.wsgi.application' WSGI_APPLICATION = 'adminpanelapp.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases # https://docs.djangoproject.com/en/4.1/ref/settings/#databases
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'bot.db'), 'NAME': BASE_DIR / 'db.sqlite3',
} }
} }
@ -101,10 +102,11 @@ AUTH_PASSWORD_VALIDATORS = [
}, },
] ]
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/ # https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = 'ru' LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC' TIME_ZONE = 'UTC'
@ -112,6 +114,7 @@ USE_I18N = True
USE_TZ = True USE_TZ = True
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/ # https://docs.djangoproject.com/en/4.1/howto/static-files/
@ -124,3 +127,9 @@ DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
ASGI_APPLICATION = 'adminpanelapp.asgi.application' ASGI_APPLICATION = 'adminpanelapp.asgi.application'
ASYNC_MODE = 'django' ASYNC_MODE = 'django'
g_telegram_bot_api_token = '6212211018:AAEwcEN0NdjbhqDiClUk8vZkE_vfRUxsReU'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

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>

15
adminpanelapp/urls.py

@ -1,6 +1,15 @@
from django.contrib import admin
from django.urls import path, include from django.urls import path, include
from .views import send_telegram_message from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [ urlpatterns = [
path('send_telegram_message/<int:chat_id>/', send_telegram_message, name='send_telegram_message'), path('admin/', admin.site.urls),
] path('', include('adminpanel.urls')),
path('', RedirectView.as_view(url='/admin/adminpanel/orders'), name='')
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

16
adminpanelapp/wsgi.py

@ -0,0 +1,16 @@
"""
WSGI config for adminpanelapp 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.1/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanelapp.settings')
application = get_wsgi_application()

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.

2
bot_modules/access.py

@ -106,7 +106,7 @@ 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_BotSubscribes, 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, None, None, init_access, a_ChildModuleNameList, 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_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)

244
bot_modules/all_orders.py

@ -4,12 +4,8 @@
# Заказы # Заказы
from bot_sys import bot_bd, keyboard, user_access, bd_table 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 mod_table_operate, mod_simple_message, orders
from bot_modules import users, user_message from template import bd_item_select, bd_item_view, bd_item
from template import bd_item_select, bd_item_view, bd_item, bd_item_edit
from enum import Enum
from enum import auto
# --------------------------------------------------------- # ---------------------------------------------------------
# БД # БД
@ -22,23 +18,14 @@ 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 = {}
button_names.update(orders.button_names) button_names.update(orders.button_names)
button_names.pop(mod_table_operate.ButtonNames.ADD) button_names.pop(mod_table_operate.ButtonNames.ADD)
cur_button_names = { cur_button_names = {
mod_simple_message.ButtonNames.START: "🛒 Все заказы", mod_simple_message.ButtonNames.START: "🛒 Все заказы",
mod_table_operate.ButtonNames.SHOW: "☐ Открыть заказ",
mod_table_operate.ButtonNames.LIST: "📃 Список текущих заказов", mod_table_operate.ButtonNames.LIST: "📃 Список текущих заказов",
orders.ButtonNames.LIST_ALL: "📃 Список всех заказов", orders.ButtonNames.LIST_ALL: "📃 Список всех заказов",
ButtonNames.SHOW_USER_INFO: "👤 Информация о пользователе",
ButtonNames.SEND_USER_MESSAGE: "📨 Отправить сообщение пользователю",
ButtonNames.ADD_TO_DESC: "𝌴 Добавить к описанию",
mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать заказ", mod_table_operate.ButtonNames.EDIT: "🛠 Редактировать заказ",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): "☐ Загрузить чек по оплате заказа", mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): "☐ Загрузить чек по оплате заказа",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в заказе", mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в заказе",
@ -69,43 +56,28 @@ cur_messages = {
Введите новый статус заказа: Введите новый статус заказа:
''', ''',
mod_table_operate.Messages.OPEN: f''' mod_table_operate.Messages.OPEN: f'''
<b>Номер заказа: #{orders.key_name} </b>
<b>Заказ: #{orders.name_field}</b> <b>Заказ: #{orders.name_field}</b>
<b>Описание и состав заказа:</b> #{orders.desc_field} <b>Описание и состав заказа:</b> #{orders.desc_field}
<b>Статус:</b> #{orders.status_field} <b>Статус:</b> #{orders.status_field}
<b>Пользователь:</b> #{orders.user_id_field} <b>Пользователь:</b> #{orders.parent_id_field}
<b>Адрес доставки:</b> #{orders.address_field} <b>Адрес доставки:</b> #{orders.address_field}
<b>Время создания:</b> #{orders.create_datetime_field} <b>Время создания:</b> #{orders.create_datetime_field}
''', ''',
mod_table_operate.InlineMessage(ButtonNames.ADD_TO_DESC): f'''
Текущее описание заказа:
<code>#{orders.desc_field}</code>
Введите дополение к описанию заказа:
''',
} }
messages_notification = { messages_notification = {
mod_table_operate.NotificationMessage(orders.OrderStatus.NEW): f'''Статус заказа "#{orders.name_field}" изменён на - ожидает модерации''', mod_table_operate.NotificationMessage(orders.OrderStatus.NEW): f'''Статус заказа "#{orders.name_field}" изменён на - ожидает модерации''',
mod_table_operate.NotificationMessage(orders.OrderStatus.PAY): 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}" изменён на - Заказ ожидает указания адреса доставки. 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}" изменён на - Заказ выполнен''', mod_table_operate.NotificationMessage(orders.OrderStatus.FINISH): f'''Статус заказа "#{orders.name_field}" изменён на - Заказ выполнен''',
} }
@ -113,16 +85,15 @@ messages.update(orders.messages_order_status)
messages.update(messages_notification) messages.update(messages_notification)
messages.update(cur_messages) messages.update(cur_messages)
def GetCurItemsTemplate(a_Bot, a_TableName, a_StatusFieldName, a_ParentIDFieldName): def GetCurItemsTemplate(a_Bot, a_TableName, a_StatusFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID): def GetBDItems(a_Message, a_UserGroups, a_ParentID):
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_StatusFieldName} != ?' request = f'SELECT * FROM {a_TableName} WHERE {a_StatusFieldName} != ?'
return a_Bot.SQLRequest(request, param = ([a_ParentID, str(orders.OrderStatus.FINISH)])) return a_Bot.SQLRequest(request, param = ([str(orders.OrderStatus.FINISH)]))
return GetBDItems return GetBDItems
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_ParentIDFieldName): def GetBDItemsForUserTemplate(a_Bot, a_TableName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID): def GetBDItems(a_Message, a_UserGroups, a_ParentID):
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ?' return bd_item.GetAllItemsTemplate(a_Bot, a_TableName)()
return a_Bot.SQLRequest(request, param = ([a_ParentID]))
return GetBDItems return GetBDItems
class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource): class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
@ -132,18 +103,19 @@ class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
def GetItemsFunc(self): def GetItemsFunc(self):
if self.m_OnlyCurrent: if self.m_OnlyCurrent:
return GetCurItemsTemplate(self.m_Bot, self.m_TableName, orders.status_field, self.m_ParentIDFieldName) return GetCurItemsTemplate(self.m_Bot, self.m_TableName, orders.status_field)
return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName) return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName)
def IsFirst(self):
return True
class ModuleAllOrders(orders.ModuleOrders): 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): 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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetInitBDCommands(self): def GetInitBDCommands(self):
# уже сделано в ModuleUserOrders # уже сделано в ModuleUserOrders
return [ return []
access_utils.GetAccessForModuleRequest(self.GetName(), self.m_InitAccess, self.m_DefInitAccess),
]
def GetName(self): def GetName(self):
return module_name return module_name
@ -157,32 +129,11 @@ class ModuleAllOrders(orders.ModuleOrders):
return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName) return DBItemForUserSelectSource(self.m_Bot, self.m_Table.GetName(), parent_id_field, a_PrevPrefix, a_ButtonName)
def GetButtonNameAndKeyValueAndAccess(self, a_Item): def GetButtonNameAndKeyValueAndAccess(self, a_Item):
user_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.USER_ID) parent_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item) n, k, a = super().GetButtonNameAndKeyValueAndAccess(a_Item)
return n + "," + str(a_Item[user_field_id]), k, a return n + ":" + str(a_Item[parent_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): 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: if a_Field.m_Destiny == bd_table.TableFieldDestiny.STATUS:
key_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY) 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) item = bd_item.GetBDItemsTemplate(self.m_Bot, self.m_Table.GetName(), key_field)(a_ItemID)
@ -191,160 +142,21 @@ class ModuleAllOrders(orders.ModuleOrders):
return return
item = item[0] 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) parent_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
status_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.STATUS) status_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.STATUS)
#print('OnChangeField', item, user_field_id, status_field_id) print('OnChangeField', item, parent_field_id, status_field_id)
owner_id = item[user_field_id] owner_id = item[parent_field_id]
new_status = item[status_field_id] new_status = item[status_field_id]
parent_id = item[parent_field_id]
msg = self.GetMessage(mod_table_operate.NotificationMessage(new_status)) 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: if not msg:
self.m_Log.Error(f'Не удалось оповестить по заказу №{a_ItemID}. Пустое сообщение для нового статуса {new_status}') self.m_Log.Error(f'Не удалось оповестить по заказу №{a_ItemID}. Пустое сообщение для нового статуса {new_status}')
return return
msg = self.UpdateMessage(msg, None, item) msg = self.UpdateMessage(msg, None, item)
inline_keyboard = None await self.m_Bot.SendMessage(
#print('new_status', str(orders.OrderStatus.PAY), new_status) owner_id,
if new_status == str(orders.OrderStatus.PAY): msg.GetDesc(),
inline_keyboard = self.GetPayInlineKeyboardFunc(a_ItemID, bd_table.TableFieldDestiny.PHOTO_PAY) msg.GetPhotoID(),
elif new_status == str(orders.OrderStatus.ADDRESS): None,
inline_keyboard = self.GetPayInlineKeyboardFunc(a_ItemID, bd_table.TableFieldDestiny.ADDRESS) None
)
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

2
bot_modules/backup.py

@ -48,7 +48,7 @@ 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_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) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, 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}');"
]

2
bot_modules/buttons.py

@ -128,7 +128,7 @@ 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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

7
bot_modules/comments.py

@ -119,21 +119,18 @@ messages = {
} }
messages_subscribes = { messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Комментарий создан''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ADD):f'''Комментарий создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):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.ANY_ITEM_DEL):f'''Комментарий удалён''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Комментарий отредактирован #item_id''', 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.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.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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

4
bot_modules/groups.py

@ -125,12 +125,12 @@ messages = {
class ModuleGroups(mod_table_operate.TableOperateModule): class ModuleGroups(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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name
def GetInitBDCommands(self): def GetInitBDCommands(self):
return super(). GetInitBDCommands() + [ return super(). GetInitBDCommands() + [
groups_utils.CreateGroupRequest(user_access.user_access_group_new) f"INSERT OR IGNORE INTO {table_name} ({name_field}, {access_field}, {create_datetime_field}) VALUES ('{user_access.user_access_group_new}', '{user_access.user_access_group_new}=-', {bot_bd.GetBDDateTimeNow()});"
] ]

6
bot_modules/groups_utils.py

@ -3,7 +3,7 @@
# Группы пользователей # Группы пользователей
from bot_sys import user_access, bot_bd from bot_sys import user_access
table_name = 'user_groups' table_name = 'user_groups'
key_name = 'groupID' key_name = 'groupID'
@ -28,7 +28,3 @@ def GetUserGroupData(a_Bot, a_UserID):
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()});"

2
bot_modules/languages.py

@ -126,7 +126,7 @@ 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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
self.m_LanguageIDs = {} self.m_LanguageIDs = {}
def GetName(self): def GetName(self):

35
bot_modules/messages.py

@ -46,11 +46,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.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): " Изменить название сообщения", mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание сообщения", mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание у сообщения",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): " Изменить доступ к сообщению", mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к сообщению",
mod_table_operate.ButtonNames.DEL: "❌ Удалить сообщение", mod_table_operate.ButtonNames.DEL: "❌ Удалить сообщение",
} }
@ -72,12 +72,9 @@ messages = {
Время создания: #{create_datetime_field} Время создания: #{create_datetime_field}
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): f''' mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.NAME): '''
Создание сообщения. Шаг 1 Создание сообщения. Шаг 1
Вы можете добавить номер родителя ID в таком формате: ИмяСообщения{'<code>?' + str(bd_table.TableFieldDestiny.PARENT_ID) + '=</code>ID'}
, чтобы сообщение было только для него
Введите название сообщения: Введите название сообщения:
''', ''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): ''' mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): '''
@ -131,7 +128,7 @@ 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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name
@ -149,7 +146,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 +163,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)

18
bot_modules/mod_simple_message.py

@ -1,6 +1,5 @@
# -*- 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 keyboard, user_access from bot_sys import keyboard, user_access
@ -17,10 +16,9 @@ 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_BotSubscribes, 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
@ -74,11 +72,10 @@ class SimpleMessageModule(mod_interface.IModule):
if len(a_ButtonDesc) >= 41: if len(a_ButtonDesc) >= 41:
print('ButtonDesc:', a_ButtonDesc) print('ButtonDesc:', a_ButtonDesc)
assert False # Телеграм не поддерживает больше assert False # Телеграм не поддерживает больше
assert a_ButtonDesc[0] != ' ', f'ButtonDesc:{a_ButtonDesc}, Телеграм не поддерживает пробелы в начале' assert a_ButtonDesc[0] != ' ' # Телеграм не поддерживает пробелы в начале
assert a_ButtonDesc[-1:] != ' ', f'ButtonDesc:{a_ButtonDesc}, Телеграм не поддерживает пробелы в конце' assert a_ButtonDesc[-1:] != ' ' # Телеграм не поддерживает пробелы в конце
btn_name = f'{self.GetName()} {str(a_ButtonName).replace("ButtonNames.", "")}' # TODO добавить проверку, что все кнопки (a_ButtonDesc) разные
assert not self.m_BotButtons.CheckDescExist(a_ButtonDesc), f'ButtonDesc:{a_ButtonDesc}, повтор имени кнопки, все кнопки должны быть разными' btn = self.m_BotButtons.CreateMessage(f'{self.GetName()} {str(a_ButtonName).replace("ButtonNames.", "")}', a_ButtonDesc, self.m_Log.GetTimeNow())
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 +83,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 +96,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):
@ -118,3 +113,4 @@ class SimpleMessageModule(mod_interface.IModule):
bd_item.GetCheckForTextFunc(self.GetButton(ButtonNames.START)) bd_item.GetCheckForTextFunc(self.GetButton(ButtonNames.START))
) )

455
bot_modules/mod_table_operate.py

@ -1,10 +1,20 @@
# -*- coding: utf8 -*- # -*- coding: utf8 -*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru> # Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
import os
import sqlite3
from aiogram.dispatcher.storage import FSMContextProxy
from asgiref.sync import sync_to_async
import requests
from adminpanel.models import Orders
# Модуль для редактирования и просмотра таблицы в БД # Модуль для редактирования и просмотра таблицы в БД
from bot_sys import keyboard, user_access, bd_table, bot_bd, bot_subscribes from bot_sys import keyboard, user_access, bd_table, bot_bd, bot_subscribes
from bot_modules import access_utils, mod_simple_message, groups_utils from bot_modules import access_utils, mod_simple_message
from bot_sys.config import g_telegram_bot_api_token
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 import FSMContext
@ -22,9 +32,6 @@ def EnumButton(a_EnumItem):
def EditMessage(a_BDTableDestiny): def EditMessage(a_BDTableDestiny):
return 'edit ' + str(a_BDTableDestiny) return 'edit ' + str(a_BDTableDestiny)
def InlineMessage(a_ButtonName):
return 'inline ' + str(a_ButtonName)
def CreateMessage(a_BDTableDestiny): def CreateMessage(a_BDTableDestiny):
return 'create ' + str(a_BDTableDestiny) return 'create ' + str(a_BDTableDestiny)
@ -38,7 +45,6 @@ def SubscribeMessage(a_EnumItem):
return 'subscribe ' + str(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()
@ -55,12 +61,6 @@ class Messages(Enum):
SELECT_TO_DELETE = auto() SELECT_TO_DELETE = auto()
SUCCESS_DELETE = auto() SUCCESS_DELETE = auto()
def GetCurItem(a_Bot, a_TableName, a_KeyName, a_KeyValue):
items = bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_KeyName)(a_KeyValue)
if len(items) == 1:
return items[0]
return None
create_fsm_create_cmd = ''' create_fsm_create_cmd = '''
class FSMCreate{a_ModName}(StatesGroup): class FSMCreate{a_ModName}(StatesGroup):
{items} {items}
@ -92,29 +92,14 @@ def MakeFSMForEdit(a_ModName, a_FieldName):
exec(cmd, globals(), _locals) exec(cmd, globals(), _locals)
return _locals['fsm'] 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_ParentModName, a_ChildModName, a_InitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, 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_BotSubscribes, a_Log)
self.m_Table = a_Table self.m_Table = a_Table
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,8 +109,8 @@ 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):
@ -141,41 +126,26 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
self.m_Table.GetInitTableRequest(), self.m_Table.GetInitTableRequest(),
] + super().GetInitBDCommands() ] + 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(): for f in self.m_Table.GetFields():
access = self.GetAccessForEditKeyboardButtons(f) access = user_access.AccessMode.EDIT
if f.m_Destiny == bd_table.TableFieldDestiny.ACCESS or f.m_Destiny == bd_table.TableFieldDestiny.DEFAULT_ACCESS:
access = user_access.AccessMode.ACCEES_EDIT
cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EditButton(f.m_Destiny)), access, self.GetAccess()),] cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EditButton(f.m_Destiny)), access, 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,32 +154,17 @@ 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() key_name_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.KEY)
name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME) name_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.NAME)
access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS) access_field_id = self.m_Table.GetFieldIDByDestiny(bd_table.TableFieldDestiny.ACCESS)
assert key_name_id != None assert key_name_id != None
@ -237,109 +192,51 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
a_Msg.UpdatePhotoID(','.join(photos)) a_Msg.UpdatePhotoID(','.join(photos))
return a_Msg 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): 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()): async def ShowMessage(a_CallbackQuery, a_Item):
lang = str(a_CallbackQuery.from_user.language_code) msg = a_Message.StaticCopy()
msg = a_Message # TODO: добавить поддержку языка в a_MessageName
# Подменяем сообщение, если оно уже есть для 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():
lang = str(a_CallbackQuery.from_user.language_code)
msg = msg.GetMessageForLang(lang).StaticCopy()
msg = self.UpdateMessage(msg, lang, a_Item, a_EnablePhoto = a_EnablePhoto) msg = self.UpdateMessage(msg, lang, a_Item, a_EnablePhoto = a_EnablePhoto)
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): 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 user_id = a_CallbackQuery.from_user.id
self.m_Log.Success(f'Элемент{a_ItemID} была удалена пользователем {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 subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_DEL
item_id = -1 item_id = -1
await self.SendSubscribe(subscribe_type, item_id, user_id, item_id) await self.SendSubscribe(subscribe_type, item_id, user_id)
subscribe_type = bot_subscribes.SubscribeType.ITEM_DEL subscribe_type = bot_subscribes.SubscribeType.ITEM_DEL
item_id = a_ItemID item_id = a_ItemID
await self.SendSubscribe(subscribe_type, item_id, user_id, item_id) await self.SendSubscribe(subscribe_type, item_id, user_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): async 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,6 +244,7 @@ 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)
def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName()) def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName())
fields = [] fields = []
@ -364,71 +262,116 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
fields += [n] fields += [n]
values += ['?'] values += ['?']
param += (def_access + f";{a_UserID}=+", ) param += (def_access + f";{a_UserID}=+", )
else: else:
fields += [n] fields += [n]
values += ['?'] values += ['?']
param += (a_ItemData[n], ) param += (a_ItemData[n], )
request = f'INSERT INTO {table_name}({",".join(fields)}) VALUES({",".join(values)})' # RETURNING {key_field} request = f'INSERT INTO {table_name}({",".join(fields)}) VALUES({",".join(values)})'
#print('request', request, param) print('request', request, param)
res, error = self.m_Bot.SQLRequest(request, commit = True, return_error = True, param = param) res, error = self.m_Bot.SQLRequest(request, commit = True, return_error = True, param = param)
#регистрация заказов (название, описание, фото и т.д.) в админке Django
async def create_order():
#получаю orderID
conn = sqlite3.connect('bot.db')
cursor = conn.cursor()
query = f"SELECT orderID FROM orders WHERE orderDesc = '{param[1]}'"
cursor.execute(query)
result = cursor.fetchone()
order_id = result[0] if result else None
conn.close()
await sync_to_async(Orders.objects.update_or_create)(
name=param[0], description=param[1], param_id=param[-1], pk=order_id)
#получаем картинку
# token = g_telegram_bot_api_token
# file_id = param[2]
# 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"]
# file_url = f"https://api.telegram.org/file/bot{token}/{file_path}"
# file_name = os.path.basename(file_path)
#
# save_path = f"media/photo/{file_name}" # Полный путь для сохранения файла
#
# response = requests.get(file_url)
# if response.status_code == 200:
# with open(save_path, 'wb') as file:
# file.write(response.content)
#
# order = await sync_to_async(Orders.objects.get)(pk=order_id)
# with open(save_path, 'rb') as file:
# await sync_to_async(order.photo_link.save)(file_name, file)
token = g_telegram_bot_api_token
file_id = param[2]
url = f"https://api.telegram.org/bot{token}/getFile?file_id={file_id}&upload.auto_scale=true"
response = requests.get(url)
data = response.json()
if data['ok']:
file_path = data["result"]["file_path"]
file_url = f"https://api.telegram.org/file/bot{token}/{file_path}"
file_name = os.path.basename(file_path)
save_path = f"media/photo/{file_name}" # Полный путь для сохранения файла
response = requests.get(file_url)
if response.status_code == 200:
with open(save_path, 'wb') as file:
file.write(response.content)
order = await sync_to_async(Orders.objects.get)(pk=order_id)
with open(save_path, 'rb') as file:
await sync_to_async(order.order_photo.save)(file_name, file)
await create_order()
print('вот это', a_ItemData)
self.OnChange() self.OnChange()
if error: if error:
self.m_Log.Error(f'Пользователь {a_UserID}. Ошибка добавления записи в таблицу {request} {param}.') self.m_Log.Error(f'Пользователь {a_UserID}. Ошибка добавления записи в таблицу {request} {param}.')
else: else:
self.m_Log.Success(f'Пользователь {a_UserID}. Добавлена запись в таблицу {request} {param}.') self.m_Log.Success(f'Пользователь {a_UserID}. Добавлена запись в таблицу {request} {param}.')
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) subscribe_type = bot_subscribes.SubscribeType.ADD
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 item_id = -1
await self.SendSubscribe(subscribe_type, item_id, a_UserID, table_item_id) await self.SendSubscribe(subscribe_type, item_id, a_UserID)
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): async def SendSubscribe(self, a_Type, a_ItemID, a_OwnerUserID):
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): for s_user_id in self.m_BotSubscribes.GetUserIDs(self.GetName(), a_Type, a_ItemID = a_ItemID):
a_BotMessage = self.GetMessage(SubscribeMessage(a_Type)) 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: if not a_BotMessage:
continue continue
if s_user_id == a_OwnerUserID: if s_user_id == a_OwnerUserID:
continue continue
a_UserID = s_user_id
a_BotMessage = a_BotMessage.StaticCopy() a_BotMessage = a_BotMessage.StaticCopy()
a_BotMessage.UpdateDesc(a_BotMessage.GetDesc().replace("#item_id", str(a_TableItem))) a_BotMessage.UpdateDesc(a_BotMessage.GetDesc().replace("#item_id", str(a_ItemID)))
a_GetButtonsFunc = None
inline_keyboard_func = None a_GetInlineButtonsFunc = None
if cur_item: a_UserID = s_user_id
a_BotMessage.UpdateDesc(self.m_Table.ReplaceAllFieldTags(a_BotMessage.GetDesc(), cur_item)) a_Message = None
inline_keyboard_func = self.GetShowItemInlineKeyboardTemplate(a_TableItem) user_groups = None
parse_mode = None
await self.SendMessageToUser(a_BotMessage, a_UserID, a_GetInlineButtonsFunc = inline_keyboard_func) await simple_message.SendMessage(self.m_Bot, a_BotMessage, a_GetButtonsFunc, a_GetInlineButtonsFunc, a_UserID, a_Message, user_groups, parse_mode=parse_mode)
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName): def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
@ -448,15 +391,14 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
self.m_GetAccessFunc,\ self.m_GetAccessFunc,\
access_mode = access_mode\ access_mode = access_mode\
) )
return a_Prefix return a_Prefix
def AdditionalKeyboardForEditTemplate(self, a_Field, user_access = user_access.AccessMode.EDIT): def AdditionalKeyboardForEditTemplate(self, a_Field):
if a_Field.m_Type == bd_table.TableFieldType.ENUM: if a_Field.m_Type == bd_table.TableFieldType.ENUM:
def KeyboardButtons(a_Message, a_UserGroups): def KeyboardButtons(a_Message, a_UserGroups):
cur_buttons = [] cur_buttons = []
for s in a_Field.m_Enum: for s in a_Field.m_Enum:
cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EnumButton(s)), user_access, self.GetAccess()),] cur_buttons += [keyboard.ButtonWithAccess(self.GetButton(EnumButton(s)), user_access.AccessMode.EDIT, self.GetAccess()),]
return keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups) return keyboard.MakeButtons(self.m_Bot, cur_buttons, a_UserGroups)
return KeyboardButtons return KeyboardButtons
return None return None
@ -474,23 +416,12 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID): async def OnChangeField(self, a_Field, a_ItemID, a_ItemData, a_EditUserID):
subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_EDIT subscribe_type = bot_subscribes.SubscribeType.ANY_ITEM_EDIT
item_id = -1 item_id = -1
await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID) await self.SendSubscribe(subscribe_type, item_id, a_EditUserID)
subscribe_type = bot_subscribes.SubscribeType.ITEM_EDIT subscribe_type = bot_subscribes.SubscribeType.ITEM_EDIT
item_id = a_ItemID item_id = a_ItemID
await self.SendSubscribe(subscribe_type, item_id, a_EditUserID, a_ItemID) await self.SendSubscribe(subscribe_type, item_id, a_EditUserID)
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): def RegisterEdit(self, a_Field, a_AccessMode = user_access.AccessMode.EDIT):
a_ButtonName = self.GetButton(EditButton(a_Field.m_Destiny)) a_ButtonName = self.GetButton(EditButton(a_Field.m_Destiny))
@ -506,17 +437,90 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
async def OnChange(a_ItemID, a_ItemData, a_EditUserID): async def OnChange(a_ItemID, a_ItemData, a_EditUserID):
await self.OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID) await self.OnChangeField(a_Field, a_ItemID, a_ItemData, a_EditUserID)
async def my_handler(fsm: FSMContextProxy):
order_id = fsm.get('orderID')
name = fsm.get('orderName')
description = fsm.get('orderDesc')
adress = fsm.get('orderAddress')
cheque = fsm.get('orderPhotoPay')
photo = fsm.get('orderPhoto')
print("Значение по ключу:", order_id, name, description, adress)
item = await sync_to_async(Orders.objects.get)(pk=order_id)
if name != None:
item.name = name
await sync_to_async(item.save)()
elif description != None:
item.description = description
await sync_to_async(item.save)()
elif adress != None:
item.adress = adress
await sync_to_async(item.save)()
elif cheque != None:
token = g_telegram_bot_api_token
url = f"https://api.telegram.org/bot{token}/getFile?file_id={cheque}"
response = requests.get(url)
data = response.json()
if data['ok']:
file_path = data["result"]["file_path"]
file_url = f"https://api.telegram.org/file/bot{token}/{file_path}"
file_name = os.path.basename(file_path)
save_path = f"media/photo/{file_name}"
response = requests.get(file_url)
if response.status_code == 200:
with open(save_path, 'wb') as file:
file.write(response.content)
order = await sync_to_async(Orders.objects.get)(pk=order_id)
with open(save_path, 'rb') as file:
await sync_to_async(order.cheque.save)(file_name, file)
elif photo != None:
token = g_telegram_bot_api_token
url = f"https://api.telegram.org/bot{token}/getFile?file_id={photo}"
response = requests.get(url)
data = response.json()
if data['ok']:
file_path = data["result"]["file_path"]
file_url = f"https://api.telegram.org/file/bot{token}/{file_path}"
file_name = os.path.basename(file_path)
save_path = f"media/photo/{file_name}"
response = requests.get(file_url)
if response.status_code == 200:
with open(save_path, 'wb') as file:
file.write(response.content)
order = await sync_to_async(Orders.objects.get)(pk=order_id)
with open(save_path, 'rb') as file:
await sync_to_async(order.order_photo.save)(file_name, file)
await my_handler(a_ItemData)
print(a_ItemData)
return self.OnChange() return self.OnChange()
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)
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc
GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc GetButtonNameAndKeyValueAndAccess = self.m_GetButtonNameAndKeyValueAndAccessFunc
GetAccess = self.m_GetAccessFunc GetAccess = self.m_GetAccessFunc
a_Prefix = self.RegisterSelect(a_ButtonName, user_access.AccessMode.VIEW, only_parent = True) a_Prefix = self.RegisterSelect(a_ButtonName, a_AccessMode, only_parent = True)
a_Prefix = bd_item_edit.EditBDItemRegisterHandlers(self.m_Bot, \ bd_item_edit.EditBDItemRegisterHandlers(self.m_Bot, \
self.SelectSourceTemplate(a_Prefix, a_ButtonName), \ self.SelectSourceTemplate(a_Prefix, a_ButtonName), \
MakeFSMForEdit(self.GetName(), a_FieldName), \ MakeFSMForEdit(self.GetName(), a_FieldName), \
self.GetMessage(Messages.SELECT_TO_EDIT), \ self.GetMessage(Messages.SELECT_TO_EDIT), \
@ -535,29 +539,11 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
field_type = a_FieldType\ 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,
)
def GetAddFields(self): def GetAddFields(self):
add_destiny = self.GetAddFieldDestinys()
fields = [] fields = []
for f in self.m_Table.GetFields(): for f in self.m_Table.GetFields():
if f.m_Destiny in add_destiny: if f.m_Destiny in (bd_table.TableFieldDestiny.NAME, bd_table.TableFieldDestiny.DESC, bd_table.TableFieldDestiny.PHOTO, bd_table.TableFieldDestiny.SUBSCRIBE_TYPE, bd_table.TableFieldDestiny.ITEM_ID, ):
fields += [f] fields += [f]
return fields return fields
@ -591,32 +577,23 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
f_id = 0 f_id = 0
f = fields[f_id] f = fields[f_id]
keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(f, user_access.AccessMode.ADD), GetKeyboard(f)) keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(f), 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) 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): for i in range(len(fields) - 1):
f = fields[i] f = fields[i]
next_f = fields[i + 1] next_f = fields[i + 1]
keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(next_f, user_access.AccessMode.ADD), GetKeyboard(next_f)) keyboard = bd_item.MixKeyboardFuncTemplate(self.AdditionalKeyboardForEditTemplate(next_f), 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}')) 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_id = len(fields) - 1
f = fields[f_id] 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}')) 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)
@ -624,12 +601,13 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
def_access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DEFAULT_ACCESS) def_access_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.DEFAULT_ACCESS)
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
parent_table_name = None parent_table_name = None
parent_key_name = None parent_key_name = None
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)
@ -651,7 +629,6 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
GetAccess,\ GetAccess,\
access_mode = user_access.AccessMode.VIEW\ access_mode = user_access.AccessMode.VIEW\
) )
self.m_ShowPrefix = a_Prefix
bd_item_view.ShowBDItemRegisterHandlers(self.m_Bot,\ bd_item_view.ShowBDItemRegisterHandlers(self.m_Bot,\
a_Prefix,\ a_Prefix,\
table_name,\ table_name,\
@ -665,9 +642,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
# Удаление # Удаление
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,8 +656,7 @@ 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:
@ -714,6 +688,9 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
bd_item.GetCheckForTextFunc(a_ButtonName)\ bd_item.GetCheckForTextFunc(a_ButtonName)\
) )
address_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.ADDRESS)
status_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.STATUS)
for f in self.m_Table.GetFields(): for f in self.m_Table.GetFields():
self.RegisterEdit(f) self.RegisterEdit(f)

7
bot_modules/needs.py

@ -120,21 +120,18 @@ messages = {
} }
messages_subscribes = { messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Потребность создана''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ADD):f'''Потребность создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):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.ANY_ITEM_DEL):f'''Потребность удалёна''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Потребность отредактирована #item_id''', 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.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.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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

118
bot_modules/orders.py

@ -1,12 +1,11 @@
# -*- 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, bot_subscribes from bot_sys import bot_bd, keyboard, user_access, bd_table, bot_subscribes
from bot_modules import mod_table_operate, mod_simple_message from bot_modules import mod_table_operate, mod_simple_message
from template import bd_item_select, bd_item_view, bd_item from template import bd_item_select, bd_item_view, bd_item
from enum import Enum from enum import Enum
from enum import auto from enum import auto
@ -22,7 +21,6 @@ module_name = 'orders'
table_name = module_name table_name = module_name
key_name = 'orderID' key_name = 'orderID'
user_id_field = 'userID'
name_field = 'orderName' name_field = 'orderName'
desc_field = 'orderDesc' desc_field = 'orderDesc'
photo_field = 'orderPhoto' photo_field = 'orderPhoto'
@ -31,17 +29,14 @@ status_field = 'orderStatus'
address_field = 'orderAddress' address_field = 'orderAddress'
access_field = 'orderAccess' access_field = 'orderAccess'
create_datetime_field = 'orderCreateDateTime' create_datetime_field = 'orderCreateDateTime'
parent_id_field = 'catID' parent_id_field = 'userID'
pay_field = bd_table.TableField(photo_pay_field, bd_table.TableFieldDestiny.PHOTO_PAY, bd_table.TableFieldType.PHOTO)
table = bd_table.Table(table_name, [ 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(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(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.PHOTO),
pay_field, bd_table.TableField(photo_pay_field, bd_table.TableFieldDestiny.PHOTO_PAY, bd_table.TableFieldType.PHOTO),
bd_table.TableField(status_field, bd_table.TableFieldDestiny.STATUS, bd_table.TableFieldType.ENUM, a_Enum = OrderStatus), 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(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(access_field, bd_table.TableFieldDestiny.ACCESS, bd_table.TableFieldType.STR),
@ -49,7 +44,7 @@ table = bd_table.Table(table_name, [
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),
]) ])
init_access = f'{user_access.user_access_group_auth_users}=vea' init_access = f'{user_access.user_access_group_new}=vea'
# --------------------------------------------------------- # ---------------------------------------------------------
# Сообщения и кнопки # Сообщения и кнопки
@ -59,12 +54,11 @@ class ButtonNames(Enum):
button_names = { button_names = {
mod_simple_message.ButtonNames.START: "🛒 Заказы", mod_simple_message.ButtonNames.START: "🛒 Заказы",
mod_table_operate.ButtonNames.SHOW: "☐ Открыть заказ",
mod_table_operate.ButtonNames.LIST: "📃 Список моих текущих заказов", mod_table_operate.ButtonNames.LIST: "📃 Список моих текущих заказов",
ButtonNames.LIST_ALL: "📃 Список всех моих заказов", ButtonNames.LIST_ALL: "📃 Список всех моих заказов",
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_PAY): "🧾 Загрузить чек по оплате моего заказа", mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO_PAY): " Загрузить чек по оплате моего заказа",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в моём заказе", mod_table_operate.EditButton(bd_table.TableFieldDestiny.PHOTO): "☐ Изменить изображение в моём заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в моём заказе", mod_table_operate.EditButton(bd_table.TableFieldDestiny.NAME): "≂ Изменить название в моём заказе",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в моём заказе", mod_table_operate.EditButton(bd_table.TableFieldDestiny.DESC): "𝌴 Изменить описание в моём заказе",
@ -85,9 +79,7 @@ messages = {
Ошибка, заказ не найден Ошибка, заказ не найден
''', ''',
mod_table_operate.Messages.OPEN: f''' mod_table_operate.Messages.OPEN: f'''
<b>Номер заказа: #{key_name} </b> <b>Заказ: #{name_field}</b>
<b>Имя заказа: #{name_field}</b>
<b>Описание и состав заказа:</b> #{desc_field} <b>Описание и состав заказа:</b> #{desc_field}
@ -110,8 +102,8 @@ messages = {
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): ''' mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): '''
Создание заказа. Шаг 3 Создание заказа. Шаг 3
Загрузите фотографию для заказа. Фото будет отображаться в его описании. Загрузите обложку для заказа (Фото):
(Если фотографии нет, то нажмите "⏩ Пропустить") Она будет отображаться в его описании.
''', ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Заказ успешно добавлен!''', mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Заказ успешно добавлен!''',
mod_table_operate.Messages.START_EDIT: ''' mod_table_operate.Messages.START_EDIT: '''
@ -135,13 +127,13 @@ messages = {
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f''' mod_table_operate.EditMessage(bd_table.TableFieldDestiny.DESC): f'''
Текущее описание заказа: Текущее описание заказа:
<code>#{desc_field}</code> #{desc_field}
Введите новое описание заказа: Введите новое описание заказа:
''', ''',
mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ADDRESS): f''' mod_table_operate.EditMessage(bd_table.TableFieldDestiny.ADDRESS): f'''
Текущий адрес заказа: Текущий адрес заказа:
#{address_field} #{desc_field}
Введите новый адрес доставки заказа (укажите, кто, когда и где его сможет забрать): Введите новый адрес доставки заказа (укажите, кто, когда и где его сможет забрать):
''', ''',
@ -171,41 +163,26 @@ messages_order_status = {
messages.update(messages_order_status) messages.update(messages_order_status)
messages_subscribes = { messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Заказ создан''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ADD):f'''Заказ создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):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.ANY_ITEM_DEL):f'''Заказ удалён''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Заказ отредактирован #item_id''', 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.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) messages.update(messages_subscribes)
def GetCurItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_ParentIDFieldName, a_StatusFieldName): def GetCurItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_StatusFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID): def GetBDItems(a_Message, a_UserGroups, a_ParentID):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_UserIDFieldName} = ? AND {a_StatusFieldName} != ?' request = f'SELECT * FROM {a_TableName} WHERE {a_UserIDFieldName} = ? AND {a_StatusFieldName} != ?'
return a_Bot.SQLRequest(request, param = ([a_ParentID, user_id, str(OrderStatus.FINISH)])) return a_Bot.SQLRequest(request, param = ([user_id, str(OrderStatus.FINISH)]))
return GetBDItems return GetBDItems
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName, a_ParentIDFieldName): def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID): def GetBDItems(a_Message, a_UserGroups, a_ParentID):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
request = f'SELECT * FROM {a_TableName} WHERE {a_ParentIDFieldName} = ? AND {a_UserIDFieldName} = ?' return bd_item.GetBDItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName)(user_id)
print('GetBDItemsForUserTemplate', user_id, request, a_ParentID)
return a_Bot.SQLRequest(request, param = ([a_ParentID, user_id]))
return GetBDItems return GetBDItems
class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource): class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
@ -215,12 +192,15 @@ class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
def GetItemsFunc(self): def GetItemsFunc(self):
if self.m_OnlyCurrent: if self.m_OnlyCurrent:
return GetCurItemsTemplate(self.m_Bot, self.m_TableName, user_id_field, self.m_ParentIDFieldName, status_field) return GetCurItemsTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName, status_field)
return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, user_id_field, self.m_ParentIDFieldName) return GetBDItemsForUserTemplate(self.m_Bot, self.m_TableName, self.m_ParentIDFieldName)
def IsFirst(self):
return True
class ModuleOrders(mod_table_operate.TableOperateModule): 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): def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, 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) super().__init__(table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName): def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
@ -232,52 +212,12 @@ class ModuleOrders(mod_table_operate.TableOperateModule):
def AddBDItemFunc(self, a_ItemData, a_UserID): def AddBDItemFunc(self, a_ItemData, a_UserID):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
a_ItemData[name_field] = '' a_ItemData[parent_id_field] = a_UserID
a_ItemData[photo_field] = ''
a_ItemData[user_id_field] = a_UserID
a_ItemData[status_field] = str(OrderStatus.NEW) a_ItemData[status_field] = str(OrderStatus.NEW)
a_ItemData[address_field] = '' a_ItemData[address_field] = ''
a_ItemData[photo_pay_field] = '0' a_ItemData[photo_pay_field] = '0'
return super().AddBDItemFunc(a_ItemData, a_UserID) 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): def GetStartKeyboardButtons(self, a_Message, a_UserGroups):
parent_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups) parent_buttons = super().GetStartKeyboardButtons(a_Message, a_UserGroups)
cur_buttons = [ cur_buttons = [
@ -321,16 +261,8 @@ class ModuleOrders(mod_table_operate.TableOperateModule):
class ModuleUserOrders(ModuleOrders): 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): 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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name 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

2
bot_modules/profile.py

@ -32,7 +32,7 @@ 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_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) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

7
bot_modules/projects.py

@ -118,21 +118,18 @@ messages = {
} }
messages_subscribes = { messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Проект создан''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ADD):f'''Проект создан''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):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.ANY_ITEM_DEL):f'''Проект удалён''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Проект отредактирован #item_id''', 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.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.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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

2
bot_modules/start.py

@ -24,7 +24,7 @@ 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_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) super().__init__(messages, button_names, init_access, a_ChildModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

30
bot_modules/subscribes.py

@ -59,14 +59,11 @@ button_names = {
mod_table_operate.EditButton(bd_table.TableFieldDestiny.SUBSCRIBE_TYPE): "𝌴 Изменить тип в моей подписке", 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.ITEM_ID): "𝌴 Изменить элемент в моей подписке",
mod_table_operate.EditButton(bd_table.TableFieldDestiny.ACCESS): "✋ Изменить доступ к моей подписке", 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.ADD): "Добавление элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_DEL): "Удаление какого либо элемента", 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.ANY_ITEM_EDIT): "Редактирование какого либо элемента",
mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ITEM_DEL): "Удаление определённого элемента", 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.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: "❌ Удалить мою подписку", mod_table_operate.ButtonNames.DEL: "❌ Удалить мою подписку",
} }
@ -105,7 +102,7 @@ messages = {
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.ITEM_ID): ''' mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.ITEM_ID): '''
Создание подписки. Шаг 3 Создание подписки. Шаг 3
Номер элемента или его родителя, на который нужно подписаться (-1, если элемента нет): Номер элемента, на который нужно подписаться (-1, если элемента нет):
''', ''',
mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Подписка успешно добавлена!''', mod_table_operate.Messages.SUCCESS_CREATE: '''✅ Подписка успешно добавлена!''',
mod_table_operate.Messages.START_EDIT: ''' mod_table_operate.Messages.START_EDIT: '''
@ -146,20 +143,23 @@ messages = {
mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Подписка успешно удалёна!''', mod_table_operate.Messages.SUCCESS_DELETE: '''✅ Подписка успешно удалёна!''',
} }
# TODO Возможно это не нужно есть же mod_table_operate.EnumButton(bot_subscribes.SubscribeType.ANY_ITEM_ADD) см. выше
messages_subs_type_status = { messages_subs_type_status = {
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_ADD): f'''Добавление элемента''', mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ADD): f'''Добавление элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ANY_ITEM_DEL): 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.ANY_ITEM_EDIT): f'''Редактирование элемента''',
mod_table_operate.EnumMessageForView(bot_subscribes.SubscribeType.ITEM_DEL): 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.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) messages.update(messages_subs_type_status)
def GetCurItemsTemplate(a_Bot, a_TableName, a_UserIDFieldName, 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_UserIDFieldName} = ? AND {a_StatusFieldName} != ?'
return a_Bot.SQLRequest(request, param = ([user_id, str(OrderStatus.FINISH)]))
return GetBDItems
def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName): def GetBDItemsForUserTemplate(a_Bot, a_TableName, a_UserIDFieldName):
def GetBDItems(a_Message, a_UserGroups, a_ParentID): def GetBDItems(a_Message, a_UserGroups, a_ParentID):
user_id = str(a_Message.from_user.id) user_id = str(a_Message.from_user.id)
@ -177,8 +177,8 @@ class DBItemForUserSelectSource(bd_item_select.DBItemSelectSource):
return True return True
class ModuleSubscribe(mod_table_operate.TableOperateModule): 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): def __init__(self, a_Table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, 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) super().__init__(table, a_Messages, a_Buttons, a_ParentModName, a_ChildModName, a_InitAccess, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName): def SelectSourceTemplate(self, a_PrevPrefix, a_ButtonName):
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID) parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
@ -211,7 +211,7 @@ class ModuleSubscribe(mod_table_operate.TableOperateModule):
class ModuleUserSubscribe(ModuleSubscribe): 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): 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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
self.UpdateSubscribes() self.UpdateSubscribes()
def GetName(self): def GetName(self):
@ -234,8 +234,8 @@ class ModuleUserSubscribe(ModuleSubscribe):
a_ItemID = s[item_id_id_field] a_ItemID = s[item_id_id_field]
a_UserID = s[user_id_id_field] a_UserID = s[user_id_id_field]
for t in bot_subscribes.SubscribeType: for t in bot_subscribes.SubscribeType:
k = mod_table_operate.EnumButton(t) k = mod_table_operate.EnumMessageForView(t)
m = button_names.get(k, None) m = messages_subs_type_status.get(k, None)
if m and m == a_Type: if m and m == a_Type:
a_Type = t a_Type = t
break break

7
bot_modules/tasks.py

@ -120,21 +120,18 @@ messages = {
} }
messages_subscribes = { messages_subscribes = {
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_ADD):f'''Задача создана''', mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ADD):f'''Задача создана''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ANY_ITEM_EDIT):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.ANY_ITEM_DEL):f'''Задача удалёна''',
mod_table_operate.SubscribeMessage(bot_subscribes.SubscribeType.ITEM_EDIT):f'''Задача отредактирована #item_id''', 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.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) 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_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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

2
bot_modules/user_in_groups.py

@ -106,7 +106,7 @@ messages = {
class ModuleUserInGroups(mod_table_operate.TableOperateModule): 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): 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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name return module_name

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]

15
bot_modules/users.py

@ -66,7 +66,7 @@ messages = {
<b>Пользователь: #{name_field}</b> <b>Пользователь: #{name_field}</b>
<b>ID:</b> #{key_name} <b>ID:</b> #{key_name}
<b>Имя:</b> @#{name_field} <b>Имя:</b> #{name_field}
<b>Имя1:</b> #{name1_field} <b>Имя1:</b> #{name1_field}
<b>Имя2:</b> #{name2_field} <b>Имя2:</b> #{name2_field}
<b>Код языка:</b> #{language_code_field} <b>Код языка:</b> #{language_code_field}
@ -128,22 +128,11 @@ messages = {
class ModuleUsers(mod_table_operate.TableOperateModule): 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): 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) super().__init__(table, messages, button_names, a_ParentModName, a_ChildModName, init_access, a_ChildModuleNameList, a_EditModuleNameList, a_Bot, a_ModuleAgregator, a_BotMessages, a_BotButtons, a_BotSubscribes, a_Log)
def GetName(self): def GetName(self):
return module_name 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]
# Работа с базой данных пользователей # Работа с базой данных пользователей

11
bot_modules/users_groups_agregator.py

@ -57,7 +57,7 @@ init_access = f'{user_access.user_access_group_new}=-'
class ModuleUsersGroupsAgregator(mod_simple_message.SimpleMessageModule): class ModuleUsersGroupsAgregator(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_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) super().__init__(messages, button_names, 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_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)
@ -99,12 +99,3 @@ class ModuleUsersGroupsAgregator(mod_simple_message.SimpleMessageModule):
bd_item.GetCheckForTextFunc(self.m_HelpButtonName) 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))

9
bot_sys/aiogram_bot.py

@ -17,6 +17,7 @@ def GetPhotoList(a_PhotoIDs):
for p in photos: for p in photos:
if p != '0' and p != '': if p != '0' and p != '':
result += [p] result += [p]
print(result)
return result return result
class AiogramBot(interfaces.IBot): class AiogramBot(interfaces.IBot):
@ -89,6 +90,9 @@ class AiogramBot(interfaces.IBot):
parse_mode = parse_mode parse_mode = parse_mode
) )
async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons): async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons):
inline_keyboard = None inline_keyboard = None
if a_InlineKeyboardButtons: if a_InlineKeyboardButtons:
@ -117,6 +121,11 @@ class AiogramBot(interfaces.IBot):
else: else:
self.m_Dispatcher.register_callback_query_handler(a_CallbackHandler, commands=commands, regexp=regexp, content_types=content_types, state=state) self.m_Dispatcher.register_callback_query_handler(a_CallbackHandler, commands=commands, regexp=regexp, content_types=content_types, state=state)
def StartPolling(self): def StartPolling(self):
executor.start_polling(self.m_Dispatcher) executor.start_polling(self.m_Dispatcher)

28
bot_sys/bd_table.py

@ -36,17 +36,6 @@ class TableFieldDestiny(Enum):
ITEM_ID = auto() ITEM_ID = auto()
ADDRESS = 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, a_Enum = None):
@ -109,16 +98,7 @@ 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): class Status(Enum):
@ -170,7 +150,5 @@ def Test():
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, f4 TEXT, UNIQUE(f1), UNIQUE(f2, f3));'
item = [10, 'i2\ni2.1', 'i3', 'i4'] item = [10, 'i2', 'i3', 'i4']
assert table.ReplaceAllFieldTags('#f1 #f2 #f3 #f4', item) == '10 i2\ni2.1 i3 i4' assert table.ReplaceAllFieldTags('#f1 #f2 #f3 #f4', item) == '10 i2 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)

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

23
bot_sys/bot_subscribes.py

@ -8,14 +8,11 @@ from enum import auto
# Тип поля в таблице # Тип поля в таблице
class SubscribeType(Enum): class SubscribeType(Enum):
ANY_ITEM_ADD = auto() ADD = auto()
ANY_ITEM_DEL = auto() ANY_ITEM_DEL = auto()
ANY_ITEM_EDIT = auto() ANY_ITEM_EDIT = auto()
ITEM_DEL = auto() ITEM_DEL = auto()
ITEM_EDIT = auto() ITEM_EDIT = auto()
ANY_ITEM_ADD_WITH_PARENT = auto()
ANY_ITEM_DEL_WITH_PARENT = auto()
ANY_ITEM_EDIT_WITH_PARENT = auto()
class BotSubscribes: class BotSubscribes:
def __init__(self): def __init__(self):
@ -33,8 +30,8 @@ class BotSubscribes:
for user_id, su in s.items(): for user_id, su in s.items():
sub_um = su.get(a_ModuleName, None) sub_um = su.get(a_ModuleName, None)
if sub_um: if sub_um:
i = sub_um.get(str(a_Type), None) t = sub_um.get(str(a_ItemID), None)
if i == str(a_ItemID): if t == a_Type:
ids.add(user_id) ids.add(user_id)
return ids return ids
@ -44,7 +41,7 @@ class BotSubscribes:
s[a_UserID] = {} s[a_UserID] = {}
if not s[a_UserID].get(a_ModuleName, None): if not s[a_UserID].get(a_ModuleName, None):
s[a_UserID][a_ModuleName] = {} s[a_UserID][a_ModuleName] = {}
s[a_UserID][a_ModuleName][str(a_Type)] = str(a_ItemID) s[a_UserID][a_ModuleName][str(a_ItemID)] = a_Type
def Test(): def Test():
a = set() a = set()
@ -60,17 +57,17 @@ def Test():
mod_1 = 'proj' mod_1 = 'proj'
mod_2 = 'backup' mod_2 = 'backup'
s = BotSubscribes() s = BotSubscribes()
s.AddSubscribe(user_id_1, mod_1, SubscribeType.ANY_ITEM_ADD) s.AddSubscribe(user_id_1, mod_1, SubscribeType.ADD)
s.AddSubscribe(user_id_2, mod_2, SubscribeType.ITEM_DEL) 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.ADD)) == 1
assert len(s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_DEL)) == 0 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 user_id_1 in s.GetUserIDs(mod_1, SubscribeType.ADD)
assert not user_id_2 in s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_ADD) assert not user_id_2 in s.GetUserIDs(mod_1, SubscribeType.ADD)
assert not user_id_3 in s.GetUserIDs(mod_1, SubscribeType.ANY_ITEM_ADD) assert not user_id_3 in s.GetUserIDs(mod_1, SubscribeType.ADD)
assert len(s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)) == 1 assert len(s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)) == 1
assert len(s.GetUserIDs(mod_2, SubscribeType.ANY_ITEM_ADD)) == 0 assert len(s.GetUserIDs(mod_2, SubscribeType.ADD)) == 0
assert user_id_2 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL) 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_1 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)
assert not user_id_3 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL) assert not user_id_3 in s.GetUserIDs(mod_2, SubscribeType.ITEM_DEL)

14
bot_sys/config.py

@ -6,11 +6,11 @@
# --------------------------------------------------------- # ---------------------------------------------------------
# API токен телеграмм бота. Создаётся с помощью @BotFather # API токен телеграмм бота. Создаётся с помощью @BotFather
# Задаётся либо прямо тут в коде, либо в файле telegram_bot_api_token_file_name # Задаётся либо прямо тут в коде, либо в файле telegram_bot_api_token_file_name
g_telegram_bot_api_token = '' g_telegram_bot_api_token = '6212211018:AAEwcEN0NdjbhqDiClUk8vZkE_vfRUxsReU'
# Пользователи имеющие полный доступ, ID можно узнать например у этого бота @GetMyIDBot # Пользователи имеющие полный доступ, ID можно узнать например у этого бота @GetMyIDBot
# Задаётся либо прямо тут в коде, либо в файле root_ids_file_name # Задаётся либо прямо тут в коде, либо в файле root_ids_file_name
g_root_ids = [] g_root_ids = [1221909008]
# Логирование событий в файл # Логирование событий в файл
g_log_to_file = True g_log_to_file = True
@ -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')
@ -59,3 +57,9 @@ def GetRootIDs():
return g_root_ids return g_root_ids
import os
import django
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanelapp.settings')
django.setup()

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):

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

30
main.py

@ -6,9 +6,7 @@ import os
from bot_sys import config, log, aiogram_bot, bot_messages, bd_table, user_access 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 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 languages, messages, buttons, users, groups, user_in_groups
from bot_modules import orders_cat, orders, all_orders, authorize from bot_modules import orders, all_orders
from bot_modules import user_message
from bot_modules import bd_version
from bot_sys import bot_subscribes from bot_sys import bot_subscribes
from bot_modules import subscribes from bot_modules import subscribes
@ -41,10 +39,8 @@ mod_buttons_name = buttons.module_name
mod_users_name = users.module_name mod_users_name = users.module_name
mod_groups_name = groups.module_name mod_groups_name = groups.module_name
mod_user_in_groups_name = user_in_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_orders_name = orders.module_name
mod_all_orders_name = all_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) mod_access = access.ModuleAccess(start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
@ -53,9 +49,6 @@ 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_users = users.ModuleUsers(None, None, start_mod_list, start_mod_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_users) g_ModuleAgregator.AddModule(mod_users)
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] child_mod_name_list = [mod_start_name, mod_users_name, mod_user_in_groups_name]
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) 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)
@ -63,7 +56,7 @@ 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_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)
g_ModuleAgregator.AddModule(mod_user_in_groups) 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] child_mod_name_list = [mod_start_name, mod_users_name, mod_groups_name, mod_user_in_groups_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) 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) g_ModuleAgregator.AddModule(mod_users_groups_agregator)
@ -102,28 +95,17 @@ mod_buttons = buttons.ModuleButtons(mod_languages_name, None, child_mod_name_lis
g_ModuleAgregator.AddModule(mod_buttons) g_ModuleAgregator.AddModule(mod_buttons)
child_mod_name_list = [mod_start_name] child_mod_name_list = [mod_start_name]
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) mod_orders = orders.ModuleUserOrders(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_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) g_ModuleAgregator.AddModule(mod_orders)
child_mod_name_list = [mod_start_name, mod_orders_cat_name] child_mod_name_list = [mod_start_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) mod_all_orders = all_orders.ModuleAllOrders(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_all_orders) g_ModuleAgregator.AddModule(mod_all_orders)
child_mod_name_list = [mod_start_name] 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) 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) 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 = [ child_mod_name_list = [
mod_profile.GetName(), mod_profile.GetName(),
mod_backup.GetName(), mod_backup.GetName(),
@ -134,8 +116,6 @@ child_mod_name_list = [
mod_orders.GetName(), mod_orders.GetName(),
mod_all_orders.GetName(), mod_all_orders.GetName(),
mod_subscribe.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(child_mod_name_list, g_Bot, g_ModuleAgregator, g_BotMessages, g_BotButtons, g_BotSubscribes, g_Log)
g_ModuleAgregator.AddModule(mod_start) g_ModuleAgregator.AddModule(mod_start)

2
manage.py

@ -6,7 +6,7 @@ import sys
def main(): def main():
"""Run administrative tasks.""" """Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanel.settings') os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'adminpanelapp.settings')
try: try:
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line
except ImportError as exc: except ImportError as exc:

9
requirements.txt

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

2
template/bd_item.py

@ -100,7 +100,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

6
template/bd_item_add.py

@ -30,7 +30,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()
@ -68,7 +68,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,7 +82,7 @@ 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 result = a_Message.text
if a_PostProcessFunc: if a_PostProcessFunc:

31
template/bd_item_edit.py

@ -18,23 +18,7 @@ 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_PostProcessFunc, 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 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): 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]
@ -47,4 +31,15 @@ def EditBDItemRegisterHandlers(a_Bot, a_SelectSource, a_FSM, a_StartMessage, a_E
await a_OnChangeFunc(item_id, a_ItemData, a_UserID) await a_OnChangeFunc(item_id, a_ItemData, a_UserID)
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_PostProcessFunc, a_AccessFunc, a_ButtonFunc, access_mode = access_mode, field_type = field_type)
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):
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_FSM, a_TableName, a_KeyName, a_FieldName, a_FinishMessageFunc, a_PostProcessFunc, a_AccessFunc, a_FinishButtonFunc, 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_PostProcessFunc, a_AccessFunc, a_FinishButtonFunc, a_OnChangeFunc, access_mode, field_type = field_type), state = a_FSM.item_field)

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())

2
template/simple_message.py

@ -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