add booru image search
This commit is contained in:
parent
2a98b55b8d
commit
f8051314cc
17 changed files with 1161 additions and 75 deletions
102
tgbot/shit/handlers.py
Normal file
102
tgbot/shit/handlers.py
Normal file
|
@ -0,0 +1,102 @@
|
|||
import requests
|
||||
from telegram import Update, InlineQueryResultPhoto
|
||||
from telegram.ext import ContextTypes
|
||||
|
||||
from tgbot.config import STICKER_SHITHOLE, BOORU_API_URL
|
||||
from tgbot.shit.hentai import QueryParams
|
||||
from tgbot.shit.render import render_text_on_image
|
||||
|
||||
|
||||
async def handle_xitter(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.inline_query.query
|
||||
|
||||
xcom = "https://x.com"
|
||||
|
||||
results = [
|
||||
{
|
||||
"type": "article",
|
||||
"id": "1",
|
||||
"title": "fix xitter links",
|
||||
"description": query.replace(xcom, "https://fxtwitter.com"),
|
||||
"input_message_content": {
|
||||
"message_text": query.replace(xcom, "https://fxtwitter.com")
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
await context.bot.answer_inline_query(update.inline_query.id, results)
|
||||
|
||||
|
||||
async def handle_red_ebalo(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
query = update.inline_query.query
|
||||
|
||||
file = render_text_on_image("tgbot/assets/red_ebalo.png", query)
|
||||
|
||||
file_id = (await context.bot.send_sticker(chat_id=STICKER_SHITHOLE, sticker=file)).sticker.file_id
|
||||
results = [
|
||||
{
|
||||
"type": "sticker",
|
||||
"id": "1",
|
||||
"sticker_file_id": file_id
|
||||
}
|
||||
]
|
||||
await context.bot.answer_inline_query(update.inline_query.id, results)
|
||||
|
||||
|
||||
async def handle_hentai(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||
|
||||
error_response = [
|
||||
{
|
||||
"type": "article",
|
||||
"id": "1",
|
||||
"title": "ERROR OCCURRED! That means, at least one of us is a retard.",
|
||||
"description": "None",
|
||||
"input_message_content": {
|
||||
"message_text": "None"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
query = update.inline_query.query
|
||||
|
||||
try:
|
||||
params = QueryParams.from_query_str(query).__dict__
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
error_response[0]["description"] = "error parsing query"
|
||||
error_response[0]["input_message_content"]["message_text"] = "error parsing query"
|
||||
return await context.bot.answer_inline_query(update.inline_query.id, error_response)
|
||||
|
||||
response = requests.post(BOORU_API_URL, json=params)
|
||||
|
||||
if response.status_code == 200:
|
||||
|
||||
posts = response.json()
|
||||
|
||||
results = []
|
||||
|
||||
for idx, post in enumerate(posts):
|
||||
booru_post_url = post["booru"]["domain"] + \
|
||||
post["booru"]["site"]["api"]["postView"] + post["id"]
|
||||
|
||||
results.append(
|
||||
InlineQueryResultPhoto(
|
||||
id="%d" % idx,
|
||||
photo_url=post["fileUrl"],
|
||||
thumbnail_url=post["previewUrl"],
|
||||
title="IMAGE #%d" % idx,
|
||||
description="Image from booru",
|
||||
caption="source -> " + booru_post_url
|
||||
)
|
||||
)
|
||||
|
||||
await context.bot.answer_inline_query(update.inline_query.id, results)
|
||||
|
||||
else:
|
||||
|
||||
print(response.text)
|
||||
|
||||
error_response[0]["description"] = "booru error"
|
||||
error_response[0]["input_message_content"]["message_text"] = response.text
|
||||
|
||||
return await context.bot.answer_inline_query(update.inline_query.id, error_response)
|
46
tgbot/shit/hentai.py
Normal file
46
tgbot/shit/hentai.py
Normal file
|
@ -0,0 +1,46 @@
|
|||
import re
|
||||
|
||||
|
||||
def combine_whitespaces(s: str) -> str:
|
||||
return re.compile(r"\s+").sub(" ", s).strip()
|
||||
|
||||
|
||||
class QueryParams:
|
||||
def __init__(self, booru: str, tags: list[str], random: bool = True, limit: int = 10):
|
||||
self.booru = booru
|
||||
self.tags = tags
|
||||
self.random = random
|
||||
self.limit = limit
|
||||
|
||||
@classmethod
|
||||
def from_query_str(cls, query: str):
|
||||
query = query.replace("hentai ", "")
|
||||
|
||||
query = combine_whitespaces(query)
|
||||
|
||||
list_ = query.split(" ")
|
||||
|
||||
booru = list_[0]
|
||||
|
||||
list_.remove(booru)
|
||||
|
||||
tags = []
|
||||
random = False
|
||||
limit = 10
|
||||
|
||||
for e in list_:
|
||||
if "random=" in e: # this is 'random' argument
|
||||
random = e.replace("random=", "").lower() == "true"
|
||||
continue
|
||||
|
||||
if "limit=" in e: # this is 'limit' argument
|
||||
limit = int(e.replace("limit=", ""))
|
||||
continue
|
||||
|
||||
tags.append(e)
|
||||
|
||||
return cls(booru, tags, random, limit)
|
||||
|
||||
def __str__(self):
|
||||
return "QueryParams(booru=" + self.booru + ", tags=" + str(self.tags) + ", random=" + str(self.random) + \
|
||||
", limit=" + str(self.limit) + ")"
|
97
tgbot/shit/render.py
Normal file
97
tgbot/shit/render.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
from PIL import Image, ImageDraw, ImageFont
|
||||
import io
|
||||
|
||||
|
||||
def render_text_on_image(input_image_path, text_to_draw, output_image_path=None,
|
||||
font_path="tgbot/assets/arial-unicode-ms-bold.ttf", font_size=52):
|
||||
image = Image.open(input_image_path)
|
||||
|
||||
draw = ImageDraw.Draw(image)
|
||||
|
||||
font = ImageFont.truetype(font_path, font_size)
|
||||
|
||||
text_color = (255, 255, 255)
|
||||
|
||||
image_width, image_height = image.size
|
||||
|
||||
def wrap_text(text, draw, font, max_width):
|
||||
words = text.split()
|
||||
lines = []
|
||||
current_line = []
|
||||
current_line_width = 0
|
||||
|
||||
for word in words:
|
||||
word_width, word_height = draw.textbbox((0, 0), word, font=font)[2:4]
|
||||
space_width = draw.textbbox((0, 0), ' ', font=font)[2]
|
||||
|
||||
if current_line and (current_line_width + word_width + space_width) > max_width:
|
||||
lines.append(' '.join(current_line))
|
||||
current_line = [word]
|
||||
current_line_width = word_width
|
||||
else:
|
||||
current_line.append(word)
|
||||
current_line_width += word_width + space_width
|
||||
|
||||
if current_line:
|
||||
lines.append(' '.join(current_line))
|
||||
|
||||
return lines
|
||||
|
||||
lines = wrap_text(text_to_draw, draw, font, image_width - 20)
|
||||
|
||||
total_text_height = sum([draw.textbbox((0, 0), line, font=font)[3] for line in lines])
|
||||
|
||||
current_y = 10
|
||||
|
||||
for line in lines:
|
||||
draw.text((10, current_y), line, font=font, fill=text_color)
|
||||
|
||||
current_y += draw.textbbox((0, 0), line, font=font)[3] + 5
|
||||
|
||||
if current_y > image_height:
|
||||
break
|
||||
|
||||
if output_image_path:
|
||||
image.save(output_image_path)
|
||||
|
||||
else:
|
||||
file = io.BytesIO()
|
||||
|
||||
image.thumbnail((512, 512))
|
||||
|
||||
image.save(file, format="WEBP")
|
||||
|
||||
file.seek(0)
|
||||
|
||||
return file
|
||||
|
||||
|
||||
WIDTH = 22
|
||||
HEIGHT = 9
|
||||
|
||||
|
||||
def image_to_string(image_file):
|
||||
img = Image.open(image_file)
|
||||
|
||||
img = img.resize((WIDTH, HEIGHT), Image.Resampling.LANCZOS)
|
||||
|
||||
img = img.convert("1")
|
||||
|
||||
# Get image dimensions
|
||||
width, height = img.size
|
||||
if width != 22 or height != 9:
|
||||
raise ValueError("The image must be exactly 22x9 pixels.")
|
||||
|
||||
# Create the string representation
|
||||
pixel_string = ""
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
# Get the pixel value (0 for black, 255 for white)
|
||||
pixel = img.getpixel((x, y))
|
||||
if pixel == 0: # Black pixel
|
||||
pixel_string += "Ń"
|
||||
else: # White pixel
|
||||
pixel_string += "…"
|
||||
pixel_string += " " # New line for each row
|
||||
|
||||
return pixel_string
|
Loading…
Add table
Add a link
Reference in a new issue