Телеграмм бот для работы с изображениями
Ребят, хочу сделать чтобы бот отсылал фотку обработанную в Pillow, однако получаю ошибку: "aiogram.utils.exceptions.BadRequest: There is no photo in the request" Подскажите, мне надо сохранить фото в памяти или в чем то еще ошибка.
handlers/main.py
from aiogram.dispatcher.filters import Command
from aiogram.types import ReplyKeyboardRemove
import re
from states.make_screen_states import make_screen_states
from dispatcher import dp, bot
from aiogram import types
from aiogram.types.input_file import InputFile
from main.main import DrawScreen
DrawScreen = DrawScreen()
@dp.message_handler(Command('make_screen'))
async def main(message: types.Message):
await message.answer('Введите название пары, например "BTCUSDT": ')
await make_screen_states.Q1.set()
@dp.message_handler(state=make_screen_states.Q1)
async def main(message: types.Message, state: FSMContext):
answer = message.text
if len(answer) > 10:
await state.finish()
await message.answer('Слишком большое название')
await message.answer(f'Повторить попытку: /make_screen')
else:
await state.update_data(pair =answer)
await message.answer('Введите тип, например "Long" или "Short"')
await make_screen_states.next()
@dp.message_handler(state=make_screen_states.Q2)
async def main(message: types.Message, state: FSMContext):
answer = message.text.lstrip().lower()
if answer != 'long' and answer != "short":
await state.finish()
await message.answer(f'Ошибка, нужно ввести "Long" или "Short"')
await message.answer(f'Повторить попытку: /make_screen')
else:
await state.update_data(type =answer)
await message.answer('Введите размер плеча, например "20" ')
await make_screen_states.next()
@dp.message_handler(state=make_screen_states.Q3)
async def main(message: types.Message, state: FSMContext):
answer = message.text.lstrip().lower()
if len(answer) > 5 or not(answer.isdigit()):
await state.finish()
await message.answer(f'Ошибка, плечо нужно выразить только числами. А также оно не должно быть слишком большое или маленькое')
await message.answer(f'Повторить попытку: /make_screen')
else:
await state.update_data(leverage = answer)
await message.answer('Введите цену входа(entry price), например "1566" ')
await make_screen_states.next()
@dp.message_handler(state=make_screen_states.Q4)
async def main(message: types.Message, state: FSMContext):
answer = message.text.lstrip().lower()
if not(answer.isdigit()):
await state.finish()
await message.answer(f'Ошибка, цена должна состоять только из цифр')
await message.answer(f'Повторить попытку: /make_screen')
else:
await state.update_data(entry_price =answer)
await message.answer('Введите текущую цену(current price), например "2477" ')
await make_screen_states.next()
@dp.message_handler(state=make_screen_states.Q5)
async def main(message: types.Message, state: FSMContext):
answer = message.text.lstrip().lower()
if not(answer.isdigit()):
await state.finish()
await message.answer(f'Ошибка, цена должна состоять только из цифр')
await message.answer(f'Повторить попытку: /make_screen')
else:
await state.update_data(current_price =answer)
data = await state.get_data()
await state.finish()
await message.answer(f'Подождите, чуток')
image = DrawScreen.get_data(data, message.chat.id)
#photo = InputFile(f"main/images/{message.chat.id}_image.jpg")
await bot.send_photo(message.chat.id, image)
#DrawScreen.delete_screen(message.chat.id)
main/main.py
from PIL import Image, ImageDraw, ImageFont
import os
class DrawScreen:
def __init__(self):
self.image = Image.open("main/images/image.png")
self.leverage_font = ImageFont.truetype("./fonts/Demo_Fonts/Fontspring-DEMO-neuevektor-a-book.otf",30)
self.coin_font = ImageFont.truetype("main/fonts/DMCAPS.TTF",30)
self.res_font = ImageFont.truetype("main/fonts/DMCAPS.TTF",95)
self.prices = ImageFont.truetype("main/fonts/DMCAPS.TTF",35)
self.percent = ImageFont.truetype("main/fonts/GolosText-Regular.ttf",95)
self.srok_font = ImageFont.truetype("main/fonts/GenerischSans-SemiBold.ttf",30)
self.green_color = (40,191,132,255)
self.red_color = (221,77,108,255)
self.orange_color = (212,174,9,255)
self.sell_buy_font = ImageFont.truetype("main/fonts/FFNort-Regular.ttf",25)
self.drawer = ImageDraw.Draw(self.image)
def is_int(self,str):
try:
int(str)
return True
except ValueError:
return False
def get_data(self,data, user_id):
coin_name = data['pair']
type = data['type']
leverage = (data['leverage']) + 'x'
entry = (data['entry_price'])
take = (data['current_price'])
if type == 'long':
res = (float(take) - float(entry)) / (float(entry) / 100)
else:
res = (float(entry) - float(take)) / (float(entry) / 100)
if len(str(res)) > 5:
new_res = ''
list = []
for i in range(5):
list.append(str(res)[i])
if list[-1] == '.':
list.pop(-1)
for i in list:
new_res += i
res = new_res
self.drawscreen(res, coin_name, leverage, entry, take, type, user_id)
def drawscreen(self, res, coin_name, leverage, entry, take, type, user_id):
#draw type
if type == 'short':
self.drawer.text((145, 185), "Продать", font=self.sell_buy_font, fill= self.red_color)
elif type == 'long':
self.drawer.text((145, 185), "Купить", font=self.sell_buy_font, fill= self.green_color)
#draw leverage
if len(str(leverage)) == 3:
self.drawer.text((338, 182), leverage, font=self.leverage_font, fill='white')
elif len(str(leverage)) == 4:
self.drawer.text((334, 182), leverage, font=self.leverage_font, fill='white')
elif len(str(leverage)) == 5:
self.drawer.text((328, 182), leverage, font=self.leverage_font, fill='white')
#draw coin_name
if len(str(coin_name)) == 6:
self.drawer.text((450, 185), coin_name, font=self.coin_font, fill='white')
self.drawer.text((570, 190), "Бессрочный", font=self.srok_font, fill='white')
if len(str(coin_name)) == 7:
self.drawer.text((450, 185), coin_name, font=self.coin_font, fill='white')
self.drawer.text((590, 190), "Бессрочный", font=self.srok_font, fill='white')
elif len(str(coin_name)) == 8:
self.drawer.text((450, 185), coin_name, font=self.coin_font, fill='white')
self.drawer.text((600, 190), "Бессрочный", font=self.srok_font, fill='white')
elif len(str(coin_name)) == 9:
self.drawer.text((450, 185), coin_name, font=self.coin_font, fill='white')
self.drawer.text((610, 190), "Бессрочный", font=self.srok_font, fill='white')
elif len(str(coin_name)) == 10:
self.drawer.text((450, 185), coin_name, font=self.coin_font, fill='white')
self.drawer.text((620, 190), "Бессрочный", font=self.srok_font, fill='white')
#draw persent
if len(str(res)) == 2:
self.drawer.text((150, 220), f"+{res}", font=self.res_font, fill=self.green_color)
self.drawer.text((325, 215), "%", font=self.percent, fill=self.green_color)
elif len(str(res)) == 3:
self.drawer.text((150, 220), f"+{res}", font=self.res_font, fill=self.green_color)
self.drawer.text((370, 215), "%", font=self.percent, fill=self.green_color)
elif len(str(res)) == 4:
self.drawer.text((120, 220), f"+{res}", font=self.res_font, fill=self.green_color)
self.drawer.text((390, 215), "%", font=self.percent, fill=self.green_color)
elif len (str(res)) == 5:
self.drawer.text((120, 220), f"+{res}", font=self.res_font, fill=self.green_color)
self.drawer.text((420, 215), "%", font=self.percent, fill=self.green_color)
#draw entry and take price
self.drawer.text((410, 330), entry, font=self.prices, fill=self.orange_color)
self.drawer.text((410, 370), take, font=self.prices, fill=self.orange_color)
self.image = self.image.convert('RGB')
return self.image
В общем суть ясна, бот задает вопросы, а потом генерирует картинку, вопрос только в том, как ее правильно отправить. Заранее спасибо
Источник: Stack Overflow на русском