dev@locazia: add client_bot & try fix background funcs

This commit is contained in:
user 2024-03-06 10:46:11 +03:00
parent 27b093bc07
commit f4b77f38e4
10 changed files with 228 additions and 17 deletions

View File

@ -4,11 +4,11 @@ from asyncio import sleep
from datetime import datetime from datetime import datetime
import asyncio, sys import asyncio, sys
from aiogram import Bot
import time import time
from app.api import app from app.api import app
from app.bot import dp from app.bot import dp as uploader_bot_dp
from app.client_bot import dp as client_bot_dp
from app.core._config import SANIC_PORT, MYSQL_URI, TELEGRAM_API_KEY from app.core._config import SANIC_PORT, MYSQL_URI, TELEGRAM_API_KEY
from app.core._utils.create_maria_tables import create_maria_tables from app.core._utils.create_maria_tables import create_maria_tables
from app.core.logger import make_log from app.core.logger import make_log
@ -70,12 +70,15 @@ if __name__ == '__main__':
if startup_target == '__main__': if startup_target == '__main__':
app.ctx.memory = Memory() app.ctx.memory = Memory()
app.ctx.memory._telegram_bot = Bot(TELEGRAM_API_KEY) app.ctx.memory._telegram_bot = Bot(TELEGRAM_API_KEY)
dp._s_memory = app.ctx.memory
uploader_bot_dp._s_memory = app.ctx.memory
client_bot_dp._s_memory = app.ctx.memory
app.ctx.memory._app = app app.ctx.memory._app = app
app.add_task(execute_queue(app)) app.add_task(execute_queue(app))
app.add_task(queue_daemon(app)) app.add_task(queue_daemon(app))
app.add_task(dp.start_polling(app.ctx.memory._telegram_bot)) app.add_task(uploader_bot_dp.start_polling(app.ctx.memory._telegram_bot))
app.add_task(client_bot_dp.start_polling(app.ctx.memory._client_telegram_bot))
app.run(host='0.0.0.0', port=SANIC_PORT) app.run(host='0.0.0.0', port=SANIC_PORT)
else: else:

View File

@ -1,3 +1,5 @@
# @MY_UploaderRobot
from datetime import datetime from datetime import datetime
from aiogram import BaseMiddleware, Dispatcher from aiogram import BaseMiddleware, Dispatcher

View File

@ -0,0 +1,80 @@
# @MY_UploaderRobot
from datetime import datetime
from aiogram import BaseMiddleware, Dispatcher
from aiogram.fsm.storage.memory import MemoryStorage
from app.client_bot.routers.index import main_router
from app.core.logger import logger
from app.core.models._telegram import Wrapped_CBotChat
from app.core.models.user import User
from app.core.storage import db_session
dp = Dispatcher(storage=MemoryStorage())
class UserDataMiddleware(BaseMiddleware):
async def __call__(self, handler, event, data):
update_body = event.message or event.callback_query
if not update_body:
return
if update_body.from_user.is_bot is True:
return
user_id = update_body.from_user.id
assert user_id >= 1
# TODO: maybe make users cache
with db_session(auto_commit=False) as session:
try:
user = session.query(User).filter_by(telegram_id=user_id).first()
except BaseException as e:
logger.error(f"Error when middleware getting user: {e}")
user = None
if user is None:
logger.debug(f"User {user_id} not found. Creating new user")
user = User(
telegram_id=user_id,
username=update_body.from_user.username,
lang_code='en',
last_use=datetime.now(),
meta=dict(first_name=update_body.from_user.first_name or '',
last_name=update_body.from_user.last_name or '', username=update_body.from_user.username,
language_code=update_body.from_user.language_code,
is_premium=update_body.from_user.is_premium),
created=datetime.now()
)
session.add(user)
session.commit()
else:
if user.username != update_body.from_user.username:
user.username = update_body.from_user.username
updated_meta_fields = {}
if user.meta.get('first_name') != update_body.from_user.first_name:
updated_meta_fields['first_name'] = update_body.from_user.first_name
if user.meta.get('last_name') != update_body.from_user.last_name:
updated_meta_fields['last_name'] = update_body.from_user.last_name
user.meta = {
**user.meta,
**updated_meta_fields
}
user.last_use = datetime.now()
session.commit()
data['user'] = user
data['db_session'] = session
data['chat_wrap'] = Wrapped_CBotChat(data['bot'], chat_id=user_id)
data['memory'] = dp._s_memory
result = await handler(event, data)
return result
dp.update.outer_middleware(UserDataMiddleware())
dp.include_router(main_router)

View File

@ -0,0 +1,81 @@
from app.core._utils.tg_process_template import tg_process_template
from app.core._keyboards import get_inline_keyboard
from app.core.logger import logger
from app.core.models.wallet_connection import WalletConnection
from app.core._blockchain.ton.connect import TonConnect, unpack_wallet_info
from app.core._config import WEB_APP_URLS
from aiogram import types, Router, F
from aiogram.filters import Command
from tonsdk.utils import Address
main_router = Router()
async def send_home_menu(chat_wrap, user, wallet_connection, **kwargs):
return await tg_process_template(
chat_wrap, user.translated('home_menu').format(
wallet_address=Address(wallet_connection.wallet_address).to_string(1, 1, 1),
name=user.front_format(plain_text=True),
), keyboard=get_inline_keyboard([
[{
'text': user.translated('ownedContent_button'),
'callback_data': 'ownedContent'
}],
[{
'text': user.translated('disconnectWallet_button'),
'callback_data': 'disconnectWallet'
}]
]), **kwargs
)
async def send_connect_wallets_list(db_session, chat_wrap, user, **kwargs):
ton_connect, ton_connection = TonConnect.by_user(db_session, user, callback_fn=())
await ton_connect.restore_connection()
wallets = ton_connect._sdk_client.get_wallets()
message_text = user.translated("connectWalletsList_menu")
return await tg_process_template(
chat_wrap, message_text,
keyboard=get_inline_keyboard([
[
{
'text': f"{wallets[i]['name']}",
'callback_data': f"initTonconnect_{wallets[i]['app_name']}"
} if i < len(wallets) else None,
{
'text': f"{wallets[i + 1]['name']}",
'callback_data': f"initTonconnect_{wallets[i + 1]['app_name']}"
} if i + 1 < len(wallets) else None,
]
for i in range(0, len(wallets), 2)
]), **kwargs
)
async def t_home_menu(__msg, **extra):
memory, user, db_session, chat_wrap = extra['memory'], extra['user'], extra['db_session'], extra['chat_wrap']
if extra.get('state'):
await extra['state'].clear()
if isinstance(__msg, types.CallbackQuery):
message_id = __msg.message.message_id
elif isinstance(__msg, types.Message):
message_id = __msg.message_id
else:
message_id = None
wallet_connection = db_session.query(WalletConnection).filter(
WalletConnection.user_id == user.id,
WalletConnection.invalidated == False
).first()
if not wallet_connection:
return await send_connect_wallets_list(db_session, chat_wrap, user, message_id=message_id)
return await send_home_menu(chat_wrap, user, wallet_connection, message_id=message_id)
main_router.message.register(t_home_menu, Command('start'))
main_router.callback_query.register(t_home_menu, F.data == 'home')
router = main_router

View File

@ -0,0 +1,38 @@
import os
import sys
import traceback
from aiogram import types, Router, F
from aiogram.filters import Command
from app.client_bot.routers.home import router as home_router
from app.core.logger import logger
main_router = Router()
main_router.include_routers(home_router)
closing_router = Router()
@closing_router.message()
async def t_index(message: types.Message, **extra):
return await message.answer(extra['user'].translated('error_unknownCommand'), parse_mode='html')
main_router.include_routers(closing_router)
@main_router.error()
async def t_index_error(err_event: types.ErrorEvent, **extra):
try:
raise err_event.exception
except BaseException as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
try:
filename = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
except:
filename = None
logger.error(f"""Error: {e}
-/ {exc_type} {exc_obj} {filename} {exc_tb.tb_frame.f_lineno}""")
traceback.print_tb(exc_tb)

View File

@ -15,6 +15,8 @@ CONFIG_FILE = os.getenv('CONFIG_FILE') or f"{UPLOADS_DIR}/../config/config"
TELEGRAM_API_KEY = os.environ.get('TELEGRAM_API_KEY') TELEGRAM_API_KEY = os.environ.get('TELEGRAM_API_KEY')
assert TELEGRAM_API_KEY, "Telegram API_KEY required" assert TELEGRAM_API_KEY, "Telegram API_KEY required"
CLIENT_TELEGRAM_API_KEY = os.environ.get('CLIENT_TELEGRAM_API_KEY')
assert CLIENT_TELEGRAM_API_KEY, "Client Telegram API_KEY required"
MYSQL_URI = os.environ['MYSQL_URI'] MYSQL_URI = os.environ['MYSQL_URI']
MYSQL_DATABASE = os.environ['MYSQL_DATABASE'] MYSQL_DATABASE = os.environ['MYSQL_DATABASE']
@ -28,7 +30,7 @@ _now_str = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
LOG_FILEPATH = f"{LOG_DIR}/{_now_str}.log" LOG_FILEPATH = f"{LOG_DIR}/{_now_str}.log"
WEB_APP_URLS = { WEB_APP_URLS = {
'uploadContent': f"https://web2-client.vercel.app/uploadContent" 'uploadContent': f"https://music-ui.letsw.app/uploadContent"
} }
ALLOWED_CONTENT_TYPES = [ ALLOWED_CONTENT_TYPES = [

View File

@ -12,10 +12,10 @@ async def main():
await send_status("indexator", f"working (seqno={seqno})") await send_status("indexator", f"working (seqno={seqno})")
seqno += 1 seqno += 1
if __name__ == '__main__': # if __name__ == '__main__':
loop = asyncio.get_event_loop() # loop = asyncio.get_event_loop()
loop.run_until_complete(main()) # loop.run_until_complete(main())
loop.close() # loop.close()

View File

@ -64,10 +64,10 @@ async def main():
await send_status("ton", f"working (seqno={sw_seqno_value})") await send_status("ton", f"working (seqno={sw_seqno_value})")
if __name__ == '__main__': # if __name__ == '__main__':
loop = asyncio.get_event_loop() # loop = asyncio.get_event_loop()
loop.run_until_complete(main()) # loop.run_until_complete(main())
loop.close() # loop.close()

View File

@ -24,10 +24,10 @@ async def main():
make_log("Uploader", f"Error: {e}", level="error") make_log("Uploader", f"Error: {e}", level="error")
await asyncio.sleep(3) await asyncio.sleep(3)
if __name__ == '__main__': # if __name__ == '__main__':
loop = asyncio.get_event_loop() # loop = asyncio.get_event_loop()
loop.run_until_complete(main()) # loop.run_until_complete(main())
loop.close() # loop.close()

View File

@ -2,7 +2,9 @@ import asyncio
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from datetime import datetime, timedelta from datetime import datetime, timedelta
from aiogram import Bot
from app.core.logger import make_log from app.core.logger import make_log
from app.core._config import TELEGRAM_API_KEY, CLIENT_TELEGRAM_API_KEY
from datetime import datetime from datetime import datetime
@ -32,6 +34,9 @@ class Memory:
} }
} }
self._telegram_bot = Bot(TELEGRAM_API_KEY)
self._client_telegram_bot = Bot(CLIENT_TELEGRAM_API_KEY)
@asynccontextmanager @asynccontextmanager
async def transaction(self, desc=""): async def transaction(self, desc=""):
make_log("Memory.transaction", f"Starting transaction; {desc}", level='debug') make_log("Memory.transaction", f"Starting transaction; {desc}", level='debug')