Compare commits

...

4 Commits

  1. 39
      README.md
  2. 0
      __init__.py
  3. 0
      adminpanel/__init__.py
  4. 131
      adminpanel/admin.py
  5. 6
      adminpanel/apps.py
  6. 44
      adminpanel/models.py
  7. 0
      adminpanel/templates/__init__.py
  8. 6
      adminpanel/templates/send_telegram_message.html
  9. 3
      adminpanel/tests.py
  10. 7
      adminpanel/urls.py
  11. 28
      adminpanel/views.py
  12. 0
      adminpanelapp/__init__.py
  13. 19
      adminpanelapp/adminpanel/models.py
  14. 0
      adminpanelapp/adminpanel/templates/__init__.py
  15. 3
      adminpanelapp/adminpanel/tests.py
  16. 0
      adminpanelapp/adminpanel/urls.py
  17. 20
      adminpanelapp/adminpanel/views.py
  18. 0
      adminpanelapp/adminpanelapp/__init__.py
  19. 16
      adminpanelapp/adminpanelapp/asgi.py
  20. 128
      adminpanelapp/adminpanelapp/settings.py
  21. 28
      adminpanelapp/adminpanelapp/urls.py
  22. 16
      adminpanelapp/adminpanelapp/wsgi.py
  23. 16
      adminpanelapp/asgi.py
  24. 0
      adminpanelapp/db.sqlite3
  25. 22
      adminpanelapp/manage.py
  26. 135
      adminpanelapp/settings.py
  27. 15
      adminpanelapp/urls.py
  28. 16
      adminpanelapp/wsgi.py
  29. 4
      bot_modules/mod_simple_message.py
  30. 163
      bot_modules/mod_table_operate.py
  31. 8
      bot_modules/orders.py
  32. 11
      bot_sys/aiogram_bot.py
  33. 10
      bot_sys/config.py
  34. 22
      manage.py
  35. 1
      requirements.txt

39
README.md

@ -17,25 +17,25 @@
3. Профиль пользователя
4. Права доступа
5. Пользователи и группы пользователей
4. Проекты
5. Задачи
6. Потребности
7. Комментарии
8. Языки (сообщения и кнопки)
9. Заказы
10. Подписки
6. Проекты
7. Задачи
8. Потребности
9. Комментарии
10. Языки (сообщения и кнопки)
11. Заказы
12. Подписки
---------
---
Данный бот позволяет создать свою площадку для взаимодействия на некоммерческой основе в мессенджере Telegram и обмениваться ресурсами и компетенциями для реализации различных проектов.
Сам бот разработан на языке программирования **Python** с использованием фреймворка **Aiogram**. База данных - **SQLite3**.
------
---
**Установка, первичная настройка и запуск**
>Для работы требуется, как минимум, Python 3.8.
> Для работы требуется, как минимум, Python 3.8.
*** Загрузка зависимостей ***
@ -45,7 +45,7 @@
`sudo apt-get install python3-modules-sqlite3`
`python3 -m pip install -r requirements.txt`
`python3 -m pip install -r requirements.txt`
*** Запуск ***
@ -65,4 +65,19 @@
## Тестовая версия
Тестовая версия запущена по ссылке
http://t.me/Test_TPlatform_bot
http://t.me/Test_TPlatform_bot
## Запуск админ панели
1. Необходимо установить пакет Django
pip install requirements.txt
2. Добавляем информацию в базу данных
python manage.py makemigrations
python manage.py migrate
3. Создаем суперпользователя, чтобы зайти в админку
python manage.py createsuperuser
Придумываем логин, почту и пароль
4. Запускаем приложение
python manage.py runserver
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,)

6
adminpanel/apps.py

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

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>

3
adminpanel/tests.py

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

7
adminpanel/urls.py

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

28
adminpanel/views.py

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

0
adminpanelapp/__init__.py

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

16
adminpanelapp/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()

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

135
adminpanelapp/settings.py

@ -0,0 +1,135 @@
"""
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/
"""
import os
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'
ASGI_APPLICATION = 'adminpanelapp.asgi.application'
ASYNC_MODE = 'django'
g_telegram_bot_api_token = '6212211018:AAEwcEN0NdjbhqDiClUk8vZkE_vfRUxsReU'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')

15
adminpanelapp/urls.py

@ -0,0 +1,15 @@
from django.contrib import admin
from django.urls import path, include
from django.views.generic import RedirectView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('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()

4
bot_modules/mod_simple_message.py

@ -1,6 +1,5 @@
# -*- 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
@ -114,3 +113,4 @@ class SimpleMessageModule(mod_interface.IModule):
bd_item.GetCheckForTextFunc(self.GetButton(ButtonNames.START))
)

163
bot_modules/mod_table_operate.py

@ -1,10 +1,20 @@
# -*- 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_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 aiogram.dispatcher import FSMContext
@ -182,6 +192,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
a_Msg.UpdatePhotoID(','.join(photos))
return a_Msg
def ShowMessageTemplate(self, a_Message, Inline_keyboard_template_func = None, a_EnablePhoto = False):
async def ShowMessage(a_CallbackQuery, a_Item):
msg = a_Message.StaticCopy()
@ -233,6 +244,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
create_datetime_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.CREATE_DATE)
parent_id_field = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.PARENT_ID)
def_access = access_utils.GetItemDefaultAccessForModule(self.m_Bot, self.GetName())
fields = []
@ -250,6 +262,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
fields += [n]
values += ['?']
param += (def_access + f";{a_UserID}=+", )
else:
fields += [n]
values += ['?']
@ -259,6 +272,78 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
print('request', request, 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()
if error:
self.m_Log.Error(f'Пользователь {a_UserID}. Ошибка добавления записи в таблицу {request} {param}.')
@ -306,7 +391,6 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
self.m_GetAccessFunc,\
access_mode = access_mode\
)
return a_Prefix
def AdditionalKeyboardForEditTemplate(self, a_Field):
@ -353,8 +437,81 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
async def OnChange(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()
table_name = self.m_Table.GetName()
key_name = self.m_Table.GetFieldNameByDestiny(bd_table.TableFieldDestiny.KEY)
edit_keyboard_func = self.m_GetEditKeyboardButtonsFunc
@ -382,6 +539,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
field_type = a_FieldType\
)
def GetAddFields(self):
fields = []
for f in self.m_Table.GetFields():
@ -443,6 +601,7 @@ class TableOperateModule(mod_simple_message.SimpleMessageModule):
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_table_name = None
parent_key_name = None
if self.m_ParentModName:

8
bot_modules/orders.py

@ -1,12 +1,11 @@
# -*- 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_modules import mod_table_operate, mod_simple_message
from template import bd_item_select, bd_item_view, bd_item
from enum import Enum
from enum import auto
@ -97,7 +96,7 @@ messages = {
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.DESC): '''
Создание заказа. Шаг 2
Введите описание заказа:
''',
mod_table_operate.CreateMessage(bd_table.TableFieldDestiny.PHOTO): '''
@ -266,3 +265,4 @@ class ModuleUserOrders(ModuleOrders):
def GetName(self):
return module_name

11
bot_sys/aiogram_bot.py

@ -1,5 +1,5 @@
#-*-coding utf-8-*-
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
# Общественное достояние, 2023, Алексей Безбородов (Alexei Bezborodov) <AlexeiBv+mirocod_platform_bot@narod.ru>
from bot_sys import interfaces, bot_bd, keyboard, user_access
@ -17,6 +17,7 @@ def GetPhotoList(a_PhotoIDs):
for p in photos:
if p != '0' and p != '':
result += [p]
print(result)
return result
class AiogramBot(interfaces.IBot):
@ -89,6 +90,9 @@ class AiogramBot(interfaces.IBot):
parse_mode = parse_mode
)
async def SendDocument(self, a_UserID, a_Document, a_Caption, a_KeyboardButtons, a_InlineKeyboardButtons):
inline_keyboard = None
if a_InlineKeyboardButtons:
@ -117,6 +121,11 @@ class AiogramBot(interfaces.IBot):
else:
self.m_Dispatcher.register_callback_query_handler(a_CallbackHandler, commands=commands, regexp=regexp, content_types=content_types, state=state)
def StartPolling(self):
executor.start_polling(self.m_Dispatcher)

10
bot_sys/config.py

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

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

1
requirements.txt

@ -1,2 +1,3 @@
aiogram==2.20
colorama==0.4.5
Django==4.1.4

Loading…
Cancel
Save