init, .gitignore

This commit is contained in:
2025-11-11 00:02:49 +01:00
commit 4e18cd0eb3
124 changed files with 16300 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
import re
import requests
import random
from io import BytesIO
from bs4 import BeautifulSoup as bs
from pyrogram import Client, filters
from pyrogram.types import Message, InputMediaPhoto
from pyrogram.errors import RPCError
from utils.misc import modules_help, prefix
@Client.on_message(filters.command("icon", prefix) & filters.me)
async def search_icon(_, message: Message):
if not len(message.command) == 2:
return await message.edit_text(
"Please provide some text to search icons from Flaticon.com."
)
query = message.text.split(maxsplit=1)[1]
await message.edit_text("Searching for icons...")
search_query = query.replace(" ", "%20")
url = f"https://www.flaticon.com/search?word={search_query}"
try:
html_content = requests.get(url).text
soup = bs(html_content, "html.parser")
results = soup.find_all(
"img",
src=re.compile(r"https://cdn-icons-png.flaticon.com/128/[0-9]+/[0-9]+.png"),
)
if not results:
return await message.edit("No results found.")
random.shuffle(results)
icons = []
for i in range(5):
icons.append(results[i]["src"].replace("128", "512"))
for icon in icons:
await message.reply_document(icon)
return await message.delete()
except Exception as e:
await message.edit(f"An error occurred: {e}")
print(f"Error: {e}")
@Client.on_message(filters.command("freepik", prefix) & filters.me)
async def freepik_search(client: Client, message: Message):
parts = message.text.split(" ", 1)
if len(parts) < 2:
await message.edit_text("Please provide a search query!")
return
query = parts[1]
limit = 5
if " ; " in query:
match, limit_str = query.split(" ; ", 1)
try:
limit = int(limit_str)
except ValueError:
await message.edit_text("Invalid limit! Using the default value of 5.")
else:
match = query
match = match.replace(" ", "%20")
await message.edit_text("Searching Freepik...")
try:
url = f"https://www.freepik.com/api/regular/search?locale=en&term={match}"
json_content = requests.get(url).json()
results = []
for i in json_content["items"]:
results.append(i["preview"]["url"])
if results is None:
return await message.edit_text("No results found.")
random.shuffle(results)
img_urls = results[:limit]
media_group = []
for img_url in img_urls:
icon = requests.get(img_url)
if icon.status_code == 200:
media_group.append(InputMediaPhoto(media=BytesIO(icon.content)))
if not media_group:
await message.edit_text("No images could be downloaded.")
return
try:
await client.send_media_group(chat_id=message.chat.id, media=media_group)
except RPCError:
await message.edit_text(
"Failed to send some images. Retrying individually..."
)
for media in media_group:
try:
await message.reply_photo(photo=media.media)
except Exception as e:
await message.edit_text(f"Error sending image: {e}")
except Exception as e:
await message.edit_text(f"Failed to fetch data: {e}")
print(f"Error: {e}")
modules_help["icons"] = {
"icon [query]": "Search for icons on Flaticon.",
"freepik [query] [limit]": "Search for images on Freepik. Limit is optional and defaults to 5.",
}
+52
View File
@@ -0,0 +1,52 @@
import os
import base64
import requests
from pyrogram import Client, filters
from pyrogram.types import Message
from utils.misc import modules_help, prefix
@Client.on_message(filters.command(["imgur"], prefix) & filters.me)
async def imgur(_, message: Message):
# Check if a reply exists
msg = await message.edit_text("🎉 Please wait. trying to upload...")
if message.reply_to_message and message.reply_to_message.photo:
# Download the photo
photo_path = await message.reply_to_message.download()
# Read the photo file and encode as base64
with open(photo_path, "rb") as file:
data = file.read()
base64_data = base64.b64encode(data)
# Set API endpoint and headers for image upload
url = "https://api.imgur.com/3/image"
headers = {"Authorization": "Client-ID a10ad04550b0648"}
# Upload image to Imgur and get URL
response = requests.post(url, headers=headers, data={"image": base64_data})
result = response.json()
await msg.edit_text(result["data"]["link"])
elif message.reply_to_message and message.reply_to_message.animation:
# Download the animation (GIF)
animation_path = await message.reply_to_message.download()
# Read the animation file and encode as base64
with open(animation_path, "rb") as file:
data = file.read()
base64_data = base64.b64encode(data)
# Set API endpoint and headers for animation upload
url = "https://api.imgur.com/3/image"
headers = {"Authorization": "Client-ID a10ad04550b0648"}
# Upload animation to Imgur and get URL
response = requests.post(url, headers=headers, data={"image": base64_data})
result = response.json()
await msg.edit_text(result["data"]["link"])
else:
await msg.edit_text(
"Please reply to a photo or animation (GIF) to upload to Imgur."
)
modules_help["imgur"] = {
"imgur [img]*": "upload a photo or animation (GIF) to imgur",
}
+55
View File
@@ -0,0 +1,55 @@
from pyrogram import Client, filters
from pyrogram.types import Message
from utils.misc import prefix, modules_help
from pyrogram import Client, filters
from pyrogram.types import Message
from pyrogram.errors import MessageNotModified
import os
import pygments
from pygments.formatters import ImageFormatter
from pygments.lexers import Python3Lexer
@Client.on_message(filters.command("ncode", prefix) & filters.me)
async def coder_print(client, message: Message):
if message.reply_to_message:
reply_message = message.reply_to_message
if reply_message.media:
download_path = await client.download_media(reply_message)
with open(download_path, "r") as file:
code = file.read()
if os.path.exists(download_path):
os.remove(download_path)
pygments.highlight(
f"{code}",
Python3Lexer(),
ImageFormatter(font_name="DejaVu Sans Mono", line_numbers=True),
"result.png",
)
try:
sent_message = await message.edit_text(
"Pasting this code on my page..."
)
await client.send_document(
chat_id=message.chat.id,
document="result.png",
caption="Code highlighted by Pygments",
reply_to_message_id=message.id,
)
except MessageNotModified:
pass
await sent_message.delete()
if os.path.exists("result.png"):
os.remove("result.png")
else:
return await message.reply_text("Please reply to a text or a file.")
else:
return await message.reply_text("Please reply to a text or a file.")
modules_help["ncode"] = {
"ncode": "Highlight the code using Pygments and send it as an image."
}
+102
View File
@@ -0,0 +1,102 @@
from pyrogram import Client, filters, enums
from pyrogram.types import Message, InputMediaPhoto
from io import BytesIO
from PIL import Image
import requests
import asyncio
from utils.misc import modules_help, prefix
# Pinterest API URL
API_URL = "https://bk9.fun/pinterest/search?q="
def resize_image(image_bytes):
try:
with Image.open(image_bytes) as img:
max_size = (1280, 1280)
if img.size > max_size:
img.thumbnail(max_size)
output = BytesIO()
img.save(output, format="JPEG")
output.seek(0)
return output
image_bytes.seek(0) # Reset pointer if not resized
return image_bytes
except Exception as e:
print(f"Error resizing image: {e}")
return image_bytes
async def download_image(url):
try:
response = requests.get(url)
if response.status_code == 200:
img_bytes = BytesIO(response.content)
return resize_image(img_bytes)
except Exception as e:
print(f"Error downloading image: {e}")
return None
@Client.on_message(filters.command("pinterest", prefix) & filters.me)
async def pinterest_search(client: Client, message: Message):
if len(message.command) < 2:
await message.edit(
"Usage: `pinterest [number] <query>`", parse_mode=enums.ParseMode.MARKDOWN
)
return
num_pics = int(message.command[1]) if message.command[1].isdigit() else 10
query = " ".join(message.command[2:])
# Update status
status_message = await message.edit(
"Searching for images...", parse_mode=enums.ParseMode.MARKDOWN
)
url = f"{API_URL}{query}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
if data.get("status"):
urls = [item["images_url"] for item in data.get("BK9", [])[:num_pics]]
images = [download_image(img_url) for img_url in urls]
# Download images
downloaded_images = await asyncio.gather(*images)
media = [
InputMediaPhoto(media=img_bytes)
for img_bytes in downloaded_images
if img_bytes
]
if media:
await status_message.edit(
"Uploading pictures...", parse_mode=enums.ParseMode.MARKDOWN
)
while media:
batch = media[:10]
media = media[10:]
await message.reply_media_group(batch)
await status_message.delete() # Delete status message after uploading
else:
await status_message.edit(
"No valid images found.", parse_mode=enums.ParseMode.MARKDOWN
)
else:
await status_message.edit(
"No images found for the given query.",
parse_mode=enums.ParseMode.MARKDOWN,
)
else:
await status_message.edit(
"An error occurred, please try again later.",
parse_mode=enums.ParseMode.MARKDOWN,
)
modules_help["pinterest"] = {
"pinterest [number]* [query]": "Get images from Pinterest. Default number of images is 10",
}
+105
View File
@@ -0,0 +1,105 @@
from utils.misc import modules_help, prefix
import requests
from pyrogram import Client, filters
from pyrogram.types import Message
from modules.url import generate_screenshot
import os
# API endpoints for reverse image search engines
SEARCH_ENGINES = {
"lens": "https://lens.google.com/uploadbyurl?url={image}",
"reverse": "https://www.google.com/searchbyimage?sbisrc=4chanx&image_url={image}&safe=off",
"tineye": "https://www.tineye.com/search?url={image}",
"bing": "https://www.bing.com/images/search?view=detailv2&iss=sbi&form=SBIVSP&sbisrc=UrlPaste&q=imgurl:{image}",
"yandex": "https://yandex.com/images/search?source=collections&&url={image}&rpt=imageview",
"saucenao": "https://saucenao.com/search.php?db=999&url={image}",
}
@Client.on_message(filters.command("risearch", prefix) & filters.reply)
async def reverse_image_search(client: Client, message: Message):
if not message.reply_to_message or not message.reply_to_message.photo:
await message.reply_text(
f"Please reply to an image with <code>{prefix}risearch [engine]</code> or <code>{prefix}risearch</code>."
)
return
command_parts = message.text.split(maxsplit=1)
engines_to_use = (
[command_parts[1].strip().lower()]
if len(command_parts) > 1 and command_parts[1].strip()
else list(SEARCH_ENGINES.keys())
)
invalid_engines = [
engine for engine in engines_to_use if engine not in SEARCH_ENGINES
]
if invalid_engines:
await message.reply_text(
f"Invalid engine(s): {', '.join(invalid_engines)}. Available: {', '.join(SEARCH_ENGINES.keys())}"
)
return
processing_message = await message.edit_text("Processing the image...")
try:
# Download and upload the image
photo_path = await message.reply_to_message.download()
img_url = upload_image(photo_path)
print(img_url)
if not img_url:
await processing_message.edit("Error: Could not upload the image.")
return
# Perform searches for the selected engines
for engine in engines_to_use:
search_url = SEARCH_ENGINES[engine].format(image=img_url)
await send_screenshot(client, message, search_url, engine)
except Exception as e:
await processing_message.edit(f"An error occurred: {e}")
finally:
if photo_path and os.path.exists(photo_path):
os.remove(photo_path)
def upload_image(photo_path):
"""Uploads an image to tmpfiles.org and returns the direct download URL."""
try:
with open(photo_path, "rb") as image_file:
response = requests.post(
"https://tmpfiles.org/api/v1/upload", files={"file": image_file}
)
if response.status_code == 200:
data = response.json()
url = data["data"]["url"]
pic_url = url.split("/")[-2] + "/" + url.split("/")[-1]
direct_download_url = url.replace(f"/{pic_url}", f"/dl/{pic_url}")
print(direct_download_url)
return direct_download_url
else:
return None
except Exception:
return None
async def send_screenshot(client, message, url, engine_name):
"""Takes a screenshot of the URL and sends it to the chat."""
screenshot_data = generate_screenshot(url)
if screenshot_data:
await client.send_photo(
message.chat.id,
screenshot_data,
caption=f"<b>{engine_name.capitalize()} Result</b>\nURL: <code>{url}</code>",
reply_to_message_id=message.id,
)
else:
await message.reply(
f"Failed to take screenshot for {engine_name.capitalize()}."
)
# Add module details to help
modules_help["risearch"] = {
"risearch": f"Reply to a photo with `{prefix}risearch [engine]` (e.g., `{prefix}risearch lens`, `{prefix}risearch bing`) "
f"\nor use `{prefix}risearch` to analyze the image with all engines.",
}
+94
View File
@@ -0,0 +1,94 @@
import asyncio
import json
import os
import shutil
import aiohttp
from pyrogram import Client, enums, filters
from pyrogram.types import Message
import requests
from utils.misc import modules_help, prefix
class AioHttp:
async def get_json(self, link):
headers = {
"accept": "*/*",
"accept-language": "en-US",
"cache-control": "no-cache",
"client-geo-region": "global",
"dnt": "1",
"pragma": "no-cache",
"priority": "u=1, i",
"sec-ch-ua": '"Chromium";v="130", "Microsoft Edge";v="130", "Not?A_Brand";v="99"',
"sec-ch-ua-mobile": "?0",
"sec-ch-ua-platform": '"Windows"',
"sec-fetch-dest": "empty",
"sec-fetch-mode": "cors",
"sec-fetch-site": "same-origin",
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0",
}
async with aiohttp.ClientSession() as session:
async with session.get(link, headers=headers) as resp:
return await resp.json()
@Client.on_message(filters.command("unsplash", prefix) & filters.me)
async def unsplash(client: Client, message: Message):
if len(message.command) > 1 and isinstance(message.command[1], str):
keyword = message.command[1]
unsplash_dir = "downloads/unsplash/"
if not os.path.exists(unsplash_dir):
os.makedirs(unsplash_dir)
if len(message.command) > 2 and 2 <= int(message.command[2]) <= 10:
await message.edit(
"<b>Getting Pictures</b>", parse_mode=enums.ParseMode.HTML
)
count = int(message.command[2])
images = []
data = await AioHttp().get_json(
f"https://unsplash.com/napi/search/photos?page=1&per_page={count}&query={keyword}"
)
while len(images) < count:
for ia in range(len(images), count):
img = data["results"][ia]["urls"]["raw"]
if img.startswith("https://images.unsplash.com/photo"):
image_content = requests.get(img).content
with open(f"{unsplash_dir}/unsplash_{ia}.jpg", "wb") as f:
f.write(image_content)
imgr = f"{unsplash_dir}/unsplash_{ia}.jpg"
images.append(imgr)
else:
images.append(img)
if len(images) == count:
break
for img in images:
await client.send_document(message.chat.id, img)
await message.delete()
shutil.rmtree(unsplash_dir)
return
else:
await message.edit(
"<b>Getting Picture</b>", parse_mode=enums.ParseMode.HTML
)
data = await AioHttp().get_json(
f"https://unsplash.com/napi/search/photos?page=1&per_page=1&query={keyword}"
)
img = data["results"][0]["urls"]["raw"]
await asyncio.gather(
message.delete(), client.send_document(message.chat.id, str(img))
)
modules_help["unsplash"] = {
"unsplash": f"[keyword]*",
"unsplash": f"[keyword]* [number of results you want]*\n"
"Makes a request to <code>unsplash.com</code> and sends the image with the keyword you provided.\n\n"
"<b>Note:</b>\n1. The number of results you can get is limited to 10.\n"
"2. Keyword is required and should be of one word only!.\n"
"3. Images are sent as document to maintain quality.",
}
+103
View File
@@ -0,0 +1,103 @@
from pyrogram import Client, filters, enums
from pyrogram.types import Message, InputMediaPhoto
from io import BytesIO
from PIL import Image
import requests
import asyncio
from utils.misc import modules_help, prefix
API_URL = "https://bk9.fun/search/unsplash?q="
def resize_image(image_bytes):
try:
with Image.open(image_bytes) as img:
max_size = (1280, 1280)
if img.size > max_size:
img.thumbnail(max_size)
output = BytesIO()
img.save(output, format="JPEG")
output.seek(0)
return output
image_bytes.seek(0) # Reset pointer if not resized
return image_bytes
except Exception as e:
print(f"Error resizing image: {e}")
return image_bytes
async def download_image(url):
try:
response = requests.get(url)
if response.status_code == 200:
img_bytes = BytesIO(response.content)
resized_img_bytes = resize_image(img_bytes)
return resized_img_bytes
except Exception as e:
print(f"Error downloading image: {e}")
return None
@Client.on_message(filters.command(["unsplash2", "usp2"], prefix) & filters.me)
async def imgsearch(client: Client, message: Message):
if len(message.command) < 2:
await message.edit(
"Usage: `img [number] <query>`", parse_mode=enums.ParseMode.MARKDOWN
)
return
num_pics = int(message.command[1]) if message.command[1].isdigit() else 10
query = " ".join(message.command[2:])
# Update status
status_message = await message.edit(
"Searching for images...", parse_mode=enums.ParseMode.MARKDOWN
)
url = f"{API_URL}{query}"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
if data.get("status"):
urls = data.get("BK9", [])[:num_pics]
images = [download_image(img_url) for img_url in urls]
# Download images
downloaded_images = await asyncio.gather(*images)
media = [
InputMediaPhoto(media=img_bytes)
for img_bytes in downloaded_images
if img_bytes
]
if media:
await status_message.edit(
"Uploading pictures...", parse_mode=enums.ParseMode.MARKDOWN
)
while media:
batch = media[:10]
media = media[10:]
await message.reply_media_group(batch)
await status_message.delete() # Delete status message after uploading
else:
await status_message.edit(
"No valid images found.", parse_mode=enums.ParseMode.MARKDOWN
)
else:
await status_message.edit(
"No images found for the given query.",
parse_mode=enums.ParseMode.MARKDOWN,
)
else:
await status_message.edit(
"An error occurred, please try again later.",
parse_mode=enums.ParseMode.MARKDOWN,
)
modules_help["unsplash2"] = {
"unsplash2 [number]* [query]": "Get HD images. Default number of images is 10",
"usp2 [number]* [query]": "Get HD images. Default number of images is 10",
}