diff --git a/plugins/autopic.py b/plugins/autopic.py
index e206a98..30a048b 100644
--- a/plugins/autopic.py
+++ b/plugins/autopic.py
@@ -10,17 +10,94 @@ import asyncio
import os
import random
from random import shuffle
-
+import aiohttp
+import re
from telethon.tl.functions.photos import UploadProfilePhotoRequest
+from PIL import Image
-from pyUltroid.fns.helper import download_file
-from pyUltroid.fns.tools import get_google_images
+from pyUltroid.fns.helper import download_file, fast_download
from . import LOGS, get_help, get_string, udB, ultroid_bot, ultroid_cmd
__doc__ = get_help("help_autopic")
+async def get_google_images(query: str):
+ """Extract image URLs from Google Images search results with fallbacks"""
+
+ headers = {
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
+ }
+
+ search_url = f"https://www.google.com/search?q={query}&tbm=isch"
+
+ # Domains to exclude
+ excluded_domains = [
+ 'gstatic.com',
+ 'google.com',
+ 'googleusercontent.com',
+ 'ssl.google.com'
+ ]
+
+ def is_valid_url(url):
+ return not any(domain in url.lower() for domain in excluded_domains)
+
+ try:
+ async with aiohttp.ClientSession() as session:
+ async with session.get(search_url, headers=headers) as response:
+ html = await response.text()
+
+ # Try to extract from search results div first
+ img_urls = []
+ search_pattern = r'
(.*?)
'
+ search_match = re.search(search_pattern, html, re.DOTALL)
+ if search_match:
+ search_content = search_match.group(1)
+ url_pattern = r'https://[^\"]*?\.(?:jpg|jpeg|png|webp)'
+ url_matches = re.finditer(url_pattern, search_content, re.IGNORECASE)
+ for url_match in url_matches:
+ url = url_match.group(0)
+ if url not in img_urls and is_valid_url(url):
+ img_urls.append(url)
+
+ # Fallback to tdeeNb div if no results
+ if not img_urls:
+ pattern = r']*>(.*?)
'
+ matches = re.finditer(pattern, html, re.DOTALL)
+ for match in matches:
+ div_content = match.group(1)
+ url_pattern = r'https://[^\"]*?\.(?:jpg|jpeg|png|webp)'
+ url_matches = re.finditer(url_pattern, div_content, re.IGNORECASE)
+ for url_match in url_matches:
+ url = url_match.group(0)
+ if url not in img_urls and is_valid_url(url):
+ img_urls.append(url)
+
+ # Fallback to general image search if still no results
+ if not img_urls:
+ pattern = r"https://[^\"]*?\.(?:jpg|jpeg|png|webp)"
+ matches = re.finditer(pattern, html, re.IGNORECASE)
+ for match in matches:
+ url = match.group(0)
+ if url not in img_urls and is_valid_url(url):
+ img_urls.append(url)
+
+ # Final fallback to data URLs if still no results
+ if not img_urls:
+ pattern = r'data:image/(?:jpeg|png|webp);base64,[^\"]*'
+ matches = re.finditer(pattern, html, re.IGNORECASE)
+ for match in matches:
+ url = match.group(0)
+ if url not in img_urls:
+ img_urls.append(url)
+
+ return img_urls
+
+ except Exception as e:
+ print(f"Error fetching Google images: {e}")
+ return []
+
+
@ultroid_cmd(pattern="autopic( (.*)|$)")
async def autopic(e):
search = e.pattern_match.group(1).strip()
@@ -30,32 +107,25 @@ async def autopic(e):
if not search:
return await e.eor(get_string("autopic_1"), time=5)
e = await e.eor(get_string("com_1"))
- gi = googleimagesdownload()
- args = {
- "keywords": search,
- "limit": 50,
- "format": "jpg",
- "output_directory": "./resources/downloads/",
- }
- try:
- pth = await gi.download(args)
- ok = pth[0][search]
- except Exception as er:
- LOGS.exception(er)
- return await e.eor(str(er))
- if not ok:
+ images = await get_google_images(search)
+ if not images:
return await e.eor(get_string("autopic_2").format(search), time=5)
await e.eor(get_string("autopic_3").format(search))
udB.set_key("AUTOPIC", search)
SLEEP_TIME = udB.get_key("SLEEP_TIME") or 1221
while True:
- for lie in ok:
+ for lie in images:
if udB.get_key("AUTOPIC") != search:
return
- file = await e.client.upload_file(lie)
- await e.client(UploadProfilePhotoRequest(file))
+ download_path, stime = await fast_download(lie, "resources/downloads/autopic.jpg")
+ img = Image.open(download_path)
+ img.save("resources/downloads/autopic.jpg")
+ file = await e.client.upload_file("resources/downloads/autopic.jpg")
+ await e.client(UploadProfilePhotoRequest(file=file))
+ os.remove("resources/downloads/autopic.jpg")
await asyncio.sleep(SLEEP_TIME)
- shuffle(ok)
+
+ shuffle(images)
if search := udB.get_key("AUTOPIC"):
@@ -69,9 +139,11 @@ if search := udB.get_key("AUTOPIC"):
if not images.get(search):
return
img = random.choice(images[search])
- filee = await download_file(img["original"], "resources/downloads/autopic.jpg")
- file = await ultroid_bot.upload_file(filee)
- await ultroid_bot(UploadProfilePhotoRequest(file))
+ filee, stime = await fast_download(img, "resources/downloads/autopic.jpg")
+ img = Image.open(filee)
+ img.save("resources/downloads/autopic.jpg")
+ file = await ultroid_bot.upload_file("resources/downloads/autopic.jpg")
+ await ultroid_bot(UploadProfilePhotoRequest(file=file))
os.remove(filee)
try:
diff --git a/plugins/stories.py b/plugins/stories.py
new file mode 100644
index 0000000..4d36ac6
--- /dev/null
+++ b/plugins/stories.py
@@ -0,0 +1,97 @@
+# Ultroid - UserBot
+# Copyright (C) 2021-2023 TeamUltroid
+#
+# This file is a part of < https://github.com/TeamUltroid/Ultroid/ >
+# PLease read the GNU Affero General Public License in
+# .
+
+"""
+✘ Commands Available -
+
+• `{i}setstory `
+ Set replied media as your story.
+
+• `{i}storydl `
+ Download and upload user stories!
+"""
+
+import os
+from contextlib import suppress
+from . import ultroid_cmd, get_string, LOGS
+
+from telethon import TelegramClient
+from telethon.tl.functions.channels import GetFullChannelRequest
+from telethon.tl.types import User, UserFull, InputPeerSelf, InputPrivacyValueAllowAll, Channel
+from telethon.tl.functions.stories import SendStoryRequest
+from telethon.tl.functions.users import GetFullUserRequest
+from telethon.events import NewMessage
+
+
+@ultroid_cmd("setstory")
+async def setStory(event: NewMessage.Event):
+ reply = await event.get_reply_message()
+ if not (reply and (reply.photo or reply.video)):
+ await event.eor("Please reply to a photo or video!", time=5)
+ return
+ msg = await event.eor(get_string("com_1"))
+ try:
+ await event.client(
+ SendStoryRequest(
+ InputPeerSelf(),
+ reply.media,
+ privacy_rules=[
+ InputPrivacyValueAllowAll()
+ ]
+ )
+ )
+ await msg.eor("🔥 **Story is Live!**", time=5)
+ except Exception as er:
+ await msg.edit(f"__ERROR: {er}__")
+ LOGS.exception(er)
+
+
+@ultroid_cmd("storydl")
+async def downloadUserStories(event: NewMessage.Event):
+ replied = await event.get_reply_message()
+ await event.eor(get_string("com_1"))
+ try:
+ username = event.text.split(maxsplit=1)[1]
+ except IndexError:
+ if replied and isinstance(replied.sender, User):
+ username = replied.sender_id
+ else:
+ return await event.eor(
+ "Please reply to a user or provide username!"
+ # get_string("story_1")
+ )
+ with suppress(ValueError):
+ username = int(username)
+ stories = None
+ try:
+ entity = await event.client.get_entity(username)
+ if isinstance(entity, Channel):
+ full_user: UserFull = (
+ await event.client(GetFullChannelRequest(entity.id))
+ ).full_channel
+ stories = full_user.stories
+ else:
+ full_user: UserFull = (
+ await event.client(GetFullUserRequest(id=username))
+ ).full_user
+ stories = full_user.stories
+ except Exception as er:
+ await event.eor(f"ERROR: __{er}__")
+ return
+
+ if not (stories and stories.stories):
+ await event.eor("ERROR: Stories not found!")
+ return
+ for story in stories.stories:
+ client: TelegramClient = event.client
+ file = await client.download_media(story.media)
+ await event.reply(
+ story.caption,
+ file=file
+ )
+ os.remove(file)
+ await event.eor("**Uploaded Stories!**", time=5)
\ No newline at end of file
diff --git a/pyUltroid/__main__.py b/pyUltroid/__main__.py
index c4d4375..9de436f 100644
--- a/pyUltroid/__main__.py
+++ b/pyUltroid/__main__.py
@@ -18,7 +18,6 @@ def main():
WasItRestart,
autopilot,
customize,
- fetch_ann,
plug,
ready,
startup_stuff,
@@ -86,12 +85,6 @@ def main():
if not udB.get_key("LOG_OFF"):
ultroid_bot.run_in_loop(ready())
- # TODO: Announcement API IS DOWN
- # if AsyncIOScheduler:
- # scheduler = AsyncIOScheduler()
- # scheduler.add_job(fetch_ann, "interval", minutes=12 * 60)
- # scheduler.start()
-
# Edit Restarting Message (if It's restarting)
ultroid_bot.run_in_loop(WasItRestart(udB))
diff --git a/pyUltroid/startup/funcs.py b/pyUltroid/startup/funcs.py
index 593a880..f5338fa 100644
--- a/pyUltroid/startup/funcs.py
+++ b/pyUltroid/startup/funcs.py
@@ -33,6 +33,7 @@ from telethon.tl.functions.channels import (
EditPhotoRequest,
InviteToChannelRequest,
)
+from telethon.tl.functions.channels import JoinChannelRequest
from telethon.tl.functions.contacts import UnblockRequest
from telethon.tl.types import (
ChatAdminRights,
@@ -431,41 +432,6 @@ async def plug(plugin_channels):
LOGS.exception(er)
-# some stuffs
-
-
-async def fetch_ann():
- from .. import asst, udB
- from ..fns.tools import async_searcher
-
- get_ = udB.get_key("OLDANN") or []
- chat_id = udB.get_key("LOG_CHANNEL")
- try:
- updts = await async_searcher(
- "https://ultroid-api.vercel.app/announcements", post=True, re_json=True
- )
- for upt in updts:
- key = list(upt.keys())[0]
- if key not in get_:
- cont = upt[key]
- if isinstance(cont, dict) and cont.get("lang"):
- if cont["lang"] != (udB.get_key("language") or "en"):
- continue
- cont = cont["msg"]
- if isinstance(cont, str):
- await asst.send_message(chat_id, cont)
- elif isinstance(cont, dict) and cont.get("chat"):
- await asst.forward_messages(chat_id, cont["msg_id"], cont["chat"])
- else:
- LOGS.info(cont)
- LOGS.info(
- "Invalid Type of Announcement Detected!\nMake sure you are on latest version.."
- )
- get_.append(key)
- udB.set_key("OLDANN", get_)
- except Exception as er:
- LOGS.exception(er)
-
async def ready():
from .. import asst, udB, ultroid_bot
@@ -506,7 +472,11 @@ async def ready():
LOGS.exception(ef)
if spam_sent and not spam_sent.media:
udB.set_key("LAST_UPDATE_LOG_SPAM", spam_sent.id)
-# TODO: await fetch_ann()
+
+ try:
+ await ultroid_bot(JoinChannelRequest("TheUltroid"))
+ except Exception as er:
+ LOGS.exception(er)
async def WasItRestart(udb):
diff --git a/pyUltroid/version.py b/pyUltroid/version.py
index 791e543..592d3fd 100644
--- a/pyUltroid/version.py
+++ b/pyUltroid/version.py
@@ -1,2 +1,2 @@
-__version__ = "2025.02.23"
-ultroid_version = "2.1"
+__version__ = "2025.05.31"
+ultroid_version = "2.1.1"
diff --git a/requirements.txt b/requirements.txt
index 6231f99..acbc790 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,6 @@
# Important Requirements here.
telethon
+gitpython
https://github.com/New-dev0/Telethon-Patch/archive/main.zip
python-decouple
python-dotenv