Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a #1

Merged
merged 6 commits into from
May 12, 2024
Merged

a #1

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ __pycache__/
.handler-saves/
.state-save/
venv/
ffmpeg.exe
ffmpeg
db.json
website/p/*
!website/p/.gitignore
3 changes: 2 additions & 1 deletion functions/ai_talk.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ async def generating_task():
curr_result = text
else:
curr_result += text
all_result += text

all_result += text

async def send_to_user(use_md=True):
nonlocal msg_id, status_task
Expand Down
10 changes: 10 additions & 0 deletions functions/simple_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,14 @@
from io import StringIO
from random import randint, choice

import ujson
from telebot.asyncio_helper import ApiTelegramException
from telebot.formatting import escape_html
from telebot.types import Message, ReplyKeyboardRemove
from telebot.util import smart_split

from functions.ai_talk import gen_init_markup
from functions.chat_cmd import todict
from helpers.bot import bot
from helpers.config import admin_chat
from helpers.db import BotDB
Expand Down Expand Up @@ -43,6 +47,12 @@ async def command_id(msg: Message):
await bot.send_message(msg.chat.id, "Теперь перешли мне любое сообщение из чата, "
"или поделись со мной контактом этого человека.\n /cancel - отмена")

@bot.message_handler(['info'], is_reply=True)
async def command_id(msg: Message):
for block in smart_split(str(msg.reply_to_message), 4000):
await bot.send_message(msg.chat.id,
f'<pre class="language-json">{escape_html(block)}</pre>')

@bot.message_handler(['rnd'])
async def command_rnd(msg: Message):
nums = re.findall(r'\d+', msg.text)
Expand Down
12 changes: 9 additions & 3 deletions helpers/chat_update.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
from os.path import isfile

from telebot.asyncio_helper import ApiTelegramException
from telebot.util import escape

from helpers.bot import bot
from helpers.config import success_vid, admin_chat
from helpers.db import BotDB
Expand Down Expand Up @@ -70,12 +73,15 @@ async def new_group_cr(chat: Chat):
markup = InlineKeyboardMarkup()
markup.add(InlineKeyboardButton("Ignore", callback_data=f"btn_ignore_{chat.id}"))
await bot.send_message(admin_chat,
f"<b>Новая группа: {chat.title} <code>{chat.id}</code></b>", reply_markup=markup)
f"<b>Новая группа: {escape(chat.title)} <code>{chat.id}</code></b>", reply_markup=markup)


async def new_private_cr(chat: Chat):
await bot.send_video(chat.id, success_vid, caption="<b>Чем я могу помочь?</b>🤔")
try:
await bot.send_video(chat.id, success_vid, caption="<b>Чем я могу помочь?</b>🤔")
except ApiTelegramException:
await bot.send_message(chat.id, "<b>Чем я могу помочь?</b>🤔")
await BotDB.new_user(chat.id, chat.first_name + n(chat.last_name, " "), chat.bio, True)
await update_user_info(await bot.get_chat(chat.id))

await bot.send_message(admin_chat, f"<b>Новый пользователь: {chat.first_name} <code>{chat.id}</code></b>")
await bot.send_message(admin_chat, f"<b>Новый пользователь: {escape(chat.first_name + ' ' + chat.last_name)} <code>{chat.id}</code></b>")
4 changes: 4 additions & 0 deletions helpers/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

is_dev = bool(os.getenv('dev', False))
bot_token = os.getenv("bot_token")
webhook_token = os.getenv("webhook_token")
replicate_key = os.getenv("replicate_key")
weather_key = os.getenv("weather_key")
tts_key = os.getenv("tts_key")
Expand All @@ -16,6 +17,9 @@
admin_chat = int(os.getenv("admin_chat"))
together_token = None

host = os.getenv("IP")
port = int(os.getenv("PORT"))

mysql_server = os.getenv("mysql_server")
mysql_user = os.getenv("mysql_user")
mysql_password = os.getenv("mysql_pw")
Expand Down
1 change: 0 additions & 1 deletion helpers/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@

import aiomysql
import ujson
# noinspection PyPackageRequirements
from pymysql.err import OperationalError

from helpers.config import mysql_server, mysql_password, mysql_user
Expand Down
40 changes: 40 additions & 0 deletions helpers/server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
from aiohttp import web

from helpers import session_manager
from helpers.bot import bot
from helpers.db import BotDB
from pathlib import Path

routes = web.RouteTableDef()

static_dir_path = Path('website')


@web.middleware
async def static_serve(request, handler):
relative_file_path = Path(request.path).relative_to('/') # remove root '/'
file_path = static_dir_path / relative_file_path # rebase into static dir
if not file_path.exists():
return web.HTTPNotFound()
if file_path.is_dir():
file_path /= 'index.html'
if not file_path.exists():
return web.HTTPNotFound()
return web.FileResponse(file_path)


async def shutdown(app):
await bot.close_session()

if BotDB.pool is not None:
await BotDB.pool.clear()

await session_manager.close_all_sessions()
print("server stopped")


async def app_factory():
app = web.Application(middlewares=[static_serve])
app.add_routes(routes)
app.on_shutdown.append(shutdown)
return app
80 changes: 36 additions & 44 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import ujson
from starlette.applications import Starlette
from starlette.responses import Response
from starlette.routing import Mount, Route, WebSocketRoute
from starlette.staticfiles import StaticFiles
from aiohttp import web
from telebot.types import Update, Message, ReplyKeyboardRemove
from telebot.util import content_type_media

from functions import voice_msg
from functions.ai_talk import AiTalk
from functions.ai_upscale import register_ai_upscale_handler
from functions.books import register_books_handler
from functions.chat_cmd import register_chat_handler
from functions.chess import chess_mp_endpoint, get_chess_games
from functions.photo_desc import register_photo_desc_handler
from functions.simple_cmds import init_simple_commands
from functions.voice_msg import register_voice_msg_handler
Expand All @@ -23,11 +17,11 @@
from helpers.db import BotDB
from helpers.gpts.gpts_apis import ChatGPT, GigaChat
from helpers.middleware import ChatManagement
from helpers.server import routes, app_factory
from helpers.timer import timer

bot.setup_middleware(ChatManagement())


# from helpers.timer import timer


Expand Down Expand Up @@ -65,18 +59,17 @@ async def command_cancel(msg: Message):
bot.register_message_handler(ai_talk_inst.start_ai_talk_listener)


@bot.message_handler(content_types=content_type_media)
async def chatting(msg: Message):
pass
# if state == "wait_for_book_name":
# book_name_upload_state(msg)
# return
# elif state == "wait_for_book" or state == "wait_for_done":
# book_upload_state(msg)
# return
# elif state == "wait_for_pub":
# wait_user_upload_state(msg, state)
# return TODO
# @bot.message_handler(content_types=content_type_media)
# async def chatting(msg: Message):
# if state == "wait_for_book_name":
# book_name_upload_state(msg)
# return
# elif state == "wait_for_book" or state == "wait_for_done":
# book_upload_state(msg)
# return
# elif state == "wait_for_pub":
# wait_user_upload_state(msg, state)
# return TODO


# @bot.callback_query_handler(None)
Expand All @@ -91,40 +84,39 @@ async def chatting(msg: Message):
# bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id)


@routes.post('/tg_webhook')
async def webhook_endpoint(request: web.Request):
if request.headers.get('X-Telegram-Bot-Api-Secret-Token') != config.webhook_token:
return web.Response(status=403)

async def webhook_endpoint(request):
await bot.process_new_updates([Update.de_json(ujson.loads(await request.body()))])
return Response()


async def startup():
await bot.set_webhook(url=config.web_url + config.bot_token)
print("server started")

data = await request.json(loads=ujson.loads)
await bot.process_new_updates([Update.de_json(data)])
return web.Response()

async def shutdown():
await bot.close_session()

if BotDB.pool is not None:
await BotDB.pool.clear()
async def set_webhook():
await bot.set_webhook(url=config.web_url + 'tg_webhook', secret_token=config.webhook_token)

await session_manager.close_all_sessions()
print("server stopped")

# routes1 = [
# Route('/chess_games', get_chess_games, methods=['GET']),
# WebSocketRoute('/cmp', chess_mp_endpoint), # chess multiplayer
# Mount('/', StaticFiles(directory='website', html=True))
# ]

routes = [
Route(f'/{config.bot_token}', webhook_endpoint, methods=['POST']),
Route('/chess_games', get_chess_games, methods=['GET']),
WebSocketRoute('/cmp', chess_mp_endpoint), # chess multiplayer
Mount('/', StaticFiles(directory='website', html=True))
]
# app = Starlette(routes=routes, on_startup=[startup], on_shutdown=[shutdown])

app = Starlette(routes=routes, on_shutdown=[shutdown])

# Запуск бота
if config.is_dev:
BotDB.loop.create_task(bot.infinity_polling(skip_pending=True))
BotDB.loop.run_until_complete(bot.delete_webhook())
BotDB.loop.run_until_complete(bot.infinity_polling(skip_pending=True))
print("polling started")
else:
BotDB.loop.create_task(startup())
BotDB.loop.run_until_complete(set_webhook())
print("server started")


BotDB.loop.create_task(timer())

web.run_app(app_factory(), host=config.host, port=config.port, loop=BotDB.loop)
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ tzdata
pyTelegramBotAPI
uvicorn
websockets
starlette
aiomysql
aiohttp
cryptography
chess
PyMySQL
8 changes: 2 additions & 6 deletions website/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
<link rel="icon" type="image/png" sizes="32x32" href="favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="favicon-16x16.png">
<link rel="manifest" href="site.webmanifest">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
<style>
.bi {
fill: currentColor;
Expand Down Expand Up @@ -363,13 +362,10 @@ <h3 class="fw-bold mb-0 fs-4">Игра в города</h3>
</svg>
</a>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz"
crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
<script>
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))

</script>
</body>
</html>