Merge branch 'bx-581-startproject' into dev

This commit is contained in:
Kseninia Mikhaylova 2024-07-05 11:46:18 +03:00
commit 1fea37ec76
6 changed files with 200 additions and 63 deletions

View File

@ -27,7 +27,11 @@ SECRET_KEY = "django-insecure-ruo!wst&sb8(f9)j5u4rda-w!673lj_-c0a%gx_t@)ff*q*2ze
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
<<<<<<< HEAD
NGROK_TEMP = "357e-193-228-134-167.ngrok-free.app" NGROK_TEMP = "357e-193-228-134-167.ngrok-free.app"
=======
NGROK_TEMP = "5f4c-193-228-134-167.ngrok-free.app"
>>>>>>> bx-581-startproject
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
"localhost", "localhost",
NGROK_TEMP, NGROK_TEMP,

77
back/poetry.lock generated
View File

@ -22,6 +22,34 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (>=0.23)"] trio = ["trio (>=0.23)"]
[[package]]
name = "apscheduler"
version = "3.10.4"
description = "In-process task scheduler with Cron-like capabilities"
optional = false
python-versions = ">=3.6"
files = [
{file = "APScheduler-3.10.4-py3-none-any.whl", hash = "sha256:fb91e8a768632a4756a585f79ec834e0e27aad5860bac7eaa523d9ccefd87661"},
{file = "APScheduler-3.10.4.tar.gz", hash = "sha256:e6df071b27d9be898e486bc7940a7be50b4af2e9da7c08f0744a96d4bd4cef4a"},
]
[package.dependencies]
pytz = "*"
six = ">=1.4.0"
tzlocal = ">=2.0,<3.dev0 || >=4.dev0"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
gevent = ["gevent"]
mongodb = ["pymongo (>=3.0)"]
redis = ["redis (>=3.0)"]
rethinkdb = ["rethinkdb (>=2.4.0)"]
sqlalchemy = ["sqlalchemy (>=1.4)"]
testing = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-tornado5"]
tornado = ["tornado (>=4.3)"]
twisted = ["twisted"]
zookeeper = ["kazoo"]
[[package]] [[package]]
name = "asgiref" name = "asgiref"
version = "3.8.1" version = "3.8.1"
@ -541,17 +569,19 @@ cli = ["click (>=5.0)"]
[[package]] [[package]]
name = "python-telegram-bot" name = "python-telegram-bot"
version = "21.2" version = "21.3"
description = "We have made you a wrapper you can't refuse" description = "We have made you a wrapper you can't refuse"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "python-telegram-bot-21.2.tar.gz", hash = "sha256:2ebb462a98f502727d108c00bb50c513a68ddaf9545298c42f13996a9acf8354"}, {file = "python-telegram-bot-21.3.tar.gz", hash = "sha256:1be3c8b6f2b7354418109daa3f23c522e82ed22e7fc904346bee0c7b4aab52ae"},
{file = "python_telegram_bot-21.2-py3-none-any.whl", hash = "sha256:af0f45d61521126de98f5bdc8a75a9df8b93d0c35d18b018181ca7648a38b017"}, {file = "python_telegram_bot-21.3-py3-none-any.whl", hash = "sha256:8f575e6da903edd1e78967b5b481455ee6b27f2804d2384029177eab165f2e93"},
] ]
[package.dependencies] [package.dependencies]
APScheduler = {version = ">=3.10.4,<3.11.0", optional = true, markers = "extra == \"job-queue\""}
httpx = ">=0.27,<1.0" httpx = ">=0.27,<1.0"
pytz = {version = ">=2018.6", optional = true, markers = "extra == \"job-queue\""}
[package.extras] [package.extras]
all = ["APScheduler (>=3.10.4,<3.11.0)", "aiolimiter (>=1.1.0,<1.2.0)", "cachetools (>=5.3.3,<5.4.0)", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "pytz (>=2018.6)", "tornado (>=6.4,<7.0)"] all = ["APScheduler (>=3.10.4,<3.11.0)", "aiolimiter (>=1.1.0,<1.2.0)", "cachetools (>=5.3.3,<5.4.0)", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "pytz (>=2018.6)", "tornado (>=6.4,<7.0)"]
@ -564,6 +594,17 @@ rate-limiter = ["aiolimiter (>=1.1.0,<1.2.0)"]
socks = ["httpx[socks]"] socks = ["httpx[socks]"]
webhooks = ["tornado (>=6.4,<7.0)"] webhooks = ["tornado (>=6.4,<7.0)"]
[[package]]
name = "pytz"
version = "2024.1"
description = "World timezone definitions, modern and historical"
optional = false
python-versions = "*"
files = [
{file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
{file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
]
[[package]] [[package]]
name = "requests" name = "requests"
version = "2.32.3" version = "2.32.3"
@ -585,6 +626,17 @@ urllib3 = ">=1.21.1,<3"
socks = ["PySocks (>=1.5.6,!=1.5.7)"] socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]] [[package]]
name = "sniffio" name = "sniffio"
version = "1.3.1" version = "1.3.1"
@ -661,6 +713,23 @@ files = [
{file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
] ]
[[package]]
name = "tzlocal"
version = "5.2"
description = "tzinfo object for the local timezone"
optional = false
python-versions = ">=3.8"
files = [
{file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
{file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
]
[package.dependencies]
tzdata = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"]
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "2.2.1" version = "2.2.1"
@ -681,4 +750,4 @@ zstd = ["zstandard (>=0.18.0)"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "58528b70db47be1cef118b365a2830312668b023e992f3aff0674f834f3c7acc" content-hash = "b0a8df55d3a7a429a89e692c2f74d3f41144a44fb1da3b108105ac9353eab7db"

View File

@ -16,7 +16,7 @@ pillow = "^10.3.0"
python-dotenv = "^1.0.1" python-dotenv = "^1.0.1"
requests = "^2.32.2" requests = "^2.32.2"
django-cors-headers = "^4.3.1" django-cors-headers = "^4.3.1"
python-telegram-bot = "^21.2" python-telegram-bot = {extras = ["job-queue"], version = "^21.3"}
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
taskipy = "^1.12.2" taskipy = "^1.12.2"

View File

@ -1,13 +1,62 @@
from asgiref.sync import async_to_sync
from django.apps import AppConfig from django.apps import AppConfig
import django.conf import asyncio
import requests import threading
import queue
import time
class TgbotConfig(AppConfig): class TgBotClass(AppConfig):
default_auto_field = "django.db.models.BigAutoField" default_auto_field = "django.db.models.BigAutoField"
name = "tgbot" name = "tgbot"
is_run = False
app = None
update_queue = None
my_queue = queue.Queue()
# @async_to_sync
async def init_bot(self):
from django.conf import settings
from .tgbot import TgBotApp
tgbot = TgBotApp()
app = await tgbot.init_tg()
await tgbot.set_webhook(f"https://{settings.TGBOT['base_url']}/api/tgbot/")
return app
async def some_function(self=None):
# await TgBotClass.app.bot.get_me()
while True:
if not TgBotClass.my_queue.empty():
item = TgBotClass.my_queue.get()
try:
await TgBotClass.app.process_update(item)
except Exception as e:
print('err')
await TgBotClass.app.process_update(item)
TgBotClass.my_queue.task_done()
time.sleep(3)
async def some_callback():
await TgBotClass.some_function()
def between_callback():
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
loop.run_until_complete(TgBotClass.some_callback())
loop.close()
def ready(self): def ready(self):
from django.conf import settings import os
requests.get(f"https://api.telegram.org/bot{settings.TGBOT['token']}/setWebhook?url=https://{settings.TGBOT['base_url']}/api/tgbot/&drop_pending_updates=true")
if os.environ.get("RUN_MAIN", None) != "true":
return
if TgBotClass.is_run:
return
TgBotClass.is_run = True
TgBotClass.app = async_to_sync(self.init_bot, force_new_loop=True)()
thread = threading.Thread(target=TgBotClass.between_callback)
thread.setDaemon(True)
thread.start()

60
back/tgbot/tgbot.py Normal file
View File

@ -0,0 +1,60 @@
from django.conf import settings
from telegram import (
ForceReply,
Update,
ReplyParameters,
)
from telegram.ext import (
Application,
CommandHandler,
MessageHandler,
filters,
CallbackContext,
)
from telegram.constants import ParseMode, ChatType
import logging
logger = logging.getLogger("root")
class TgBotApp:
_app = None
async def start(self, update: Update, context: CallbackContext):
user = update.effective_user
# logger.info(update)
await update.message.reply_html(
rf"Hi {user.mention_html()}!",
# reply_markup=ForceReply(selective=True),
reply_parameters=ReplyParameters(message_id=update.message.message_id),
)
async def set_webhook(self, url):
if not self._app:
logger.error("no app")
return
app = self._app
await app.bot.set_webhook(url, allowed_updates=Update.ALL_TYPES)
async def init_tg(self):
self._app = (
Application.builder()
.token(settings.TGBOT["token"])
.concurrent_updates(True)
.updater(None)
.build()
)
self._app.add_handler(CommandHandler("start", self.start))
self._app.add_handler(MessageHandler(filters.ChatType.PRIVATE, self.start))
logger.info(
{
"app": self._app,
"bot": self._app.bot,
"handlers": self._app.handlers,
}
)
await self._app.initialize()
await self._app.start()
return self._app

View File

@ -1,15 +1,14 @@
import json import json
from django.conf import settings
from telegram import Update from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
from telegram.constants import ParseMode, ChatType
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
import time
from .apps import TgBotClass
from .models import Item from .models import Item
from .serializers import ItemSerializer from .serializers import ItemSerializer
@ -18,11 +17,6 @@ import logging
logger = logging.getLogger("root") logger = logging.getLogger("root")
async def start(update, context):
logger.info(update)
await update.message.reply_html(text="123")
class ItemViewSet(viewsets.ViewSet): class ItemViewSet(viewsets.ViewSet):
queryset = Item.objects.all() queryset = Item.objects.all()
serializer_class = ItemSerializer serializer_class = ItemSerializer
@ -30,49 +24,10 @@ class ItemViewSet(viewsets.ViewSet):
@async_to_sync @async_to_sync
async def create(self, request): async def create(self, request):
req = json.loads(request.body) req = json.loads(request.body)
update_item = Update.de_json(data=req, bot=TgBotClass.app.bot)
TgBotClass.my_queue.put(update_item)
logger.info(
f"Update from {update_item.message.chat.id} pass to que and its size is {TgBotClass.my_queue.qsize()}"
)
logger.info(f"que len before put {ptb_application.update_queue.qsize()}") return Response({"result": "pass data to tgbot"})
update_item = Update.de_json(data=req, bot=ptb_application.bot)
await ptb_application.update_queue.put(update_item)
logger.info(f"que len after put {ptb_application.update_queue.qsize()}")
# await self.ptb_application.bot.send_message(
# chat_id=req["message"]["from"]["id"],
# text=f'Вы прислали текст `{req["message"]["text"]}`',
# parse_mode=ParseMode.MARKDOWN_V2,
# reply_to_message_id=req["message"]["message_id"],
# )
# if req["message"]["chat"]["type"] != ChatType.PRIVATE:
# return Response()
# if req["message"]["text"] == "/add":
# await self.ptb_application.bot.send_message(
# chat_id=req["message"]["from"]["id"],
# text=f'Вы хотите создать новую инвентаризацию?',
# parse_mode=ParseMode.MARKDOWN_V2,
# reply_to_message_id=req["message"]["message_id"],
# )
return Response({"test": "create"})
async def init_tg():
ptb_application = (
Application.builder().token(settings.TGBOT["token"]).concurrent_updates(True).updater(None).build()
)
ptb_application.add_handler(CommandHandler("start", start))
ptb_application.add_handler(
MessageHandler(filters.ChatType.PRIVATE, callback=start)
)
logger.info(
{
"app": ptb_application,
"bot": ptb_application.bot,
"handlers": ptb_application.handlers,
}
)
await ptb_application.initialize()
await ptb_application.start()
return ptb_application
ptb_application = async_to_sync(init_tg)()