Big Update And Some Fixing Code (#86)

- AutoFix Code Using DeepSource
- Fix os not defined when got error
- Fix Set Chat Photo (Only support photo)
- Fix Admins Permission Error
- Fix KeyError in Scraper
- Fix Help Module in Eval
- Fix Media Caption Too Long in IMDB
- Remove heroku support
- Some minor fix..
This commit is contained in:
yasirarism 2023-06-22 05:52:30 +00:00 committed by GitHub
parent a283daedb8
commit 68d006607f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
88 changed files with 2641 additions and 1149 deletions

View file

@ -1,32 +0,0 @@
name: PyLint
on: [pull_request, workflow_dispatch]
jobs:
Pylint_Fix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Python
uses: actions/setup-python@v1
with:
python-version: 3.9
- name: Install Python lint libraries
run: |
pip install autoflake black
- name: Remove unused imports and variables
run: |
autoflake --in-place --recursive --exclude "__main__.py" --remove-all-unused-imports --remove-unused-variables --ignore-init-module-imports .
- name: lint with black
run: |
black --exclude "__main__.py" --line-length 250 --target-version py310 .
# commit changes
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: 'reformating: code'
commit_options: '--no-verify'
repository: .
commit_user_name: yasirarism
commit_user_email: yasiramunandar@gmail.com
commit_author: yasirarism <yasiramunandar@gmail.com>

View file

@ -1,13 +1,14 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com> # * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2022-12-01 09:12:27 # * @date 2022-12-01 09:12:27
# * @lastModified 2022-12-01 09:27:31
# * @projectName MissKatyPyro # * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved # * Copyright ©YasirPedia All rights reserved
# Base Docker # Base Docker Using Ubuntu 23.04, Python 3.11 and Built In Pip
FROM yasirarism/misskaty-docker:latest FROM yasirarism/misskaty-docker:latest
ENV HOSTNAME yasirvps # Set Hostname
ENV HOSTNAME misskaty
# Copy Files
COPY . . COPY . .
# Set CMD Bot # Set CMD Bot
CMD ["bash", "start.sh"] CMD ["bash", "start.sh"]

View file

@ -50,7 +50,7 @@
🌱 [Ko-Fi](kofi-url)<br> 🌱 [Ko-Fi](kofi-url)<br>
## [4] Notes ## [4] Notes
Jika Anda ingin membantu saya memperbaiki beberapa kesalahan di bot saya, Anda dapat membuat permintaan tarik ke repo ini. Saya sangat senang jika Anda dapat membantu saya. Anda juga dapat memberikan dukungan kepada saya untuk membeli server. Jika Anda ingin membantu saya memperbaiki beberapa kesalahan di bot saya, Anda dapat membuat PR ke repo ini. Saya sangat senang jika Anda dapat membantu saya. Anda juga dapat memberikan dukungan kepada saya untuk membeli server.
## [5] Features ## [5] Features
@ -108,7 +108,7 @@ pip3 install -r requirements.txt
``` ```
pip3 install -r requirements.txt --break-system-packages pip3 install -r requirements.txt --break-system-packages
``` ```
- Atur config.env Anda atau melalui env saat menjalankan bot. Jangan lupa isi semua value yang diminta dan perlu isi *FF_MPEG_NAME* dan *VCSI_NAME* jika Anda menggunakan metode ini. - Atur config environment saat menjalankan bot dan jangan lupa isi semua value yang wajib di isi.
- Jalankan Bot - Jalankan Bot
``` ```
bash start.sh bash start.sh

View file

@ -108,7 +108,7 @@ pip3 install -r requirements.txt
``` ```
pip3 install -r requirements.txt --break-system-packages pip3 install -r requirements.txt --break-system-packages
``` ```
- Setting your config.env or via environment. Dont forget fill all required value and need fill *FF_MPEG_NAME* and *VCSI_NAME* if you're deploying using this method. - Setting your config.env or via environment and dont forget fill all required value.
- Run Bot - Run Bot
``` ```
bash start.sh bash start.sh

View file

@ -2,18 +2,21 @@ from database import dbname
gbansdb = dbname.gban gbansdb = dbname.gban
async def is_gbanned_user(user_id: int) -> bool: async def is_gbanned_user(user_id: int) -> bool:
user = await gbansdb.find_one({"user_id": user_id}) user = await gbansdb.find_one({"user_id": user_id})
return bool(user) return bool(user)
async def add_gban_user(user_id: int): async def add_gban_user(user_id: int):
is_gbanned = await is_gbanned_user(user_id) is_gbanned = await is_gbanned_user(user_id)
if is_gbanned: if is_gbanned:
return return
return await gbansdb.insert_one({"user_id": user_id}) return await gbansdb.insert_one({"user_id": user_id})
async def remove_gban_user(user_id: int): async def remove_gban_user(user_id: int):
is_gbanned = await is_gbanned_user(user_id) is_gbanned = await is_gbanned_user(user_id)
if not is_gbanned: if not is_gbanned:
return return
return await gbansdb.delete_one({"user_id": user_id}) return await gbansdb.delete_one({"user_id": user_id})

View file

@ -1,5 +1,7 @@
from pyrogram.enums import ChatType
from typing import Iterable from typing import Iterable
from pyrogram.enums import ChatType
from database import dbname from database import dbname
localesdb = dbname.locale # DB for localization localesdb = dbname.locale # DB for localization
@ -8,7 +10,11 @@ group_types: Iterable[ChatType] = (ChatType.GROUP, ChatType.SUPERGROUP)
async def set_db_lang(chat_id: int, chat_type: str, lang_code: str): async def set_db_lang(chat_id: int, chat_type: str, lang_code: str):
await localesdb.update_one({"chat_id": chat_id}, {"$set": {"lang": lang_code, "chat_type": chat_type.value}}, upsert=True) await localesdb.update_one(
{"chat_id": chat_id},
{"$set": {"lang": lang_code, "chat_type": chat_type.value}},
upsert=True,
)
async def get_db_lang(chat_id: int) -> str: async def get_db_lang(chat_id: int) -> str:

View file

@ -15,7 +15,17 @@ async def get_userdata(user_id: int) -> bool:
async def add_userdata(user_id: int, username, first_name, last_name): async def add_userdata(user_id: int, username, first_name, last_name):
await matadb.update_one({"user_id": user_id}, {"$set": {"username": username, "first_name": first_name, "last_name": last_name}}, upsert=True) await matadb.update_one(
{"user_id": user_id},
{
"$set": {
"username": username,
"first_name": first_name,
"last_name": last_name,
}
},
upsert=True,
)
# Enable Mata MissKaty in Selected Chat # Enable Mata MissKaty in Selected Chat

View file

@ -10,7 +10,8 @@ class Database:
self.col = self.db.users self.col = self.db.users
self.grp = self.db.groups self.grp = self.db.groups
def new_user(self, id, name): @staticmethod
def new_user(id, name):
return dict( return dict(
id=id, id=id,
name=name, name=name,
@ -20,7 +21,8 @@ class Database:
), ),
) )
def new_group(self, id, title): @staticmethod
def new_group(id, title):
return dict( return dict(
id=id, id=id,
title=title, title=title,
@ -84,14 +86,18 @@ class Database:
is_disabled=False, is_disabled=False,
reason="", reason="",
) )
await self.grp.update_one({"id": int(id)}, {"$set": {"chat_status": chat_status}}) await self.grp.update_one(
{"id": int(id)}, {"$set": {"chat_status": chat_status}}
)
async def disable_chat(self, chat, reason="No Reason"): async def disable_chat(self, chat, reason="No Reason"):
chat_status = dict( chat_status = dict(
is_disabled=True, is_disabled=True,
reason=reason, reason=reason,
) )
await self.grp.update_one({"id": int(chat)}, {"$set": {"chat_status": chat_status}}) await self.grp.update_one(
{"id": int(chat)}, {"$set": {"chat_status": chat_status}}
)
async def total_chat_count(self): async def total_chat_count(self):
return await self.grp.count_documents({}) return await self.grp.count_documents({})

View file

@ -1,14 +1,27 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import time import time
from logging import ERROR, INFO, StreamHandler, basicConfig, getLogger, handlers from logging import ERROR, INFO, StreamHandler, basicConfig, getLogger, handlers
from apscheduler.jobstores.mongodb import MongoDBJobStore from apscheduler.jobstores.mongodb import MongoDBJobStore
from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.schedulers.asyncio import AsyncIOScheduler
from async_pymongo import AsyncClient
from motor.motor_asyncio import AsyncIOMotorClient from motor.motor_asyncio import AsyncIOMotorClient
from pymongo import MongoClient from pymongo import MongoClient
from pyrogram import Client from pyrogram import Client
from misskaty.core import misskaty_patch from misskaty.core import misskaty_patch
from misskaty.vars import API_HASH, API_ID, BOT_TOKEN, DATABASE_URI, TZ, USER_SESSION, DATABASE_NAME from misskaty.vars import (
API_HASH,
API_ID,
BOT_TOKEN,
DATABASE_NAME,
DATABASE_URI,
TZ,
USER_SESSION,
)
basicConfig( basicConfig(
level=INFO, level=INFO,
@ -28,9 +41,7 @@ MOD_NOLOAD = ["subscene_dl"]
HELPABLE = {} HELPABLE = {}
cleanmode = {} cleanmode = {}
botStartTime = time.time() botStartTime = time.time()
misskaty_version = "v2.7 - Stable" misskaty_version = "v2.8.7 - Stable"
pymonclient = MongoClient(DATABASE_URI)
# Pyrogram Bot Client # Pyrogram Bot Client
app = Client( app = Client(
@ -38,7 +49,7 @@ app = Client(
api_id=API_ID, api_id=API_ID,
api_hash=API_HASH, api_hash=API_HASH,
bot_token=BOT_TOKEN, bot_token=BOT_TOKEN,
mongodb=dict(uri=DATABASE_URI, remove_peers=False), mongodb=dict(connection=AsyncClient(DATABASE_URI), remove_peers=False),
) )
# Pyrogram UserBot Client # Pyrogram UserBot Client
@ -47,9 +58,9 @@ user = Client(
session_string=USER_SESSION, session_string=USER_SESSION,
) )
jobstores = {"default": MongoDBJobStore(client=pymonclient, database=DATABASE_NAME, collection="nightmode")} jobstores = {"default": MongoDBJobStore(client=MongoClient(DATABASE_URI), database=DATABASE_NAME, collection="nightmode")}
scheduler = AsyncIOScheduler(jobstores=jobstores, timezone=TZ) scheduler = AsyncIOScheduler(jobstores=jobstores, timezone=TZ)
app.start() app.start()
BOT_ID = app.me.id BOT_ID = app.me.id
BOT_NAME = app.me.first_name BOT_NAME = app.me.first_name

View file

@ -15,27 +15,19 @@ from logging import getLogger
from pyrogram import __version__, idle from pyrogram import __version__, idle
from pyrogram.raw.all import layer from pyrogram.raw.all import layer
from misskaty import ( from database import dbname
BOT_NAME, from misskaty import BOT_NAME, BOT_USERNAME, HELPABLE, UBOT_NAME, app, scheduler
BOT_USERNAME,
HELPABLE,
UBOT_NAME,
app,
scheduler
)
from misskaty.plugins import ALL_MODULES from misskaty.plugins import ALL_MODULES
from misskaty.plugins.web_scraper import web from misskaty.plugins.web_scraper import web
from misskaty.vars import SUDO, USER_SESSION from misskaty.vars import SUDO, USER_SESSION
from utils import auto_clean from utils import auto_clean
from database import dbname
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
# Run Bot # Run Bot
async def start_bot(): async def start_bot():
global HELPABLE
for module in ALL_MODULES: for module in ALL_MODULES:
imported_module = importlib.import_module(f"misskaty.plugins.{module}") imported_module = importlib.import_module(f"misskaty.plugins.{module}")
if hasattr(imported_module, "__MODULE__") and imported_module.__MODULE__: if hasattr(imported_module, "__MODULE__") and imported_module.__MODULE__:
@ -79,13 +71,18 @@ async def start_bot():
for key, value in web.items(): for key, value in web.items():
await webdb.insert_one({key: value}) await webdb.insert_one({key: value})
if os.path.exists("restart.pickle"): if os.path.exists("restart.pickle"):
with open('restart.pickle', 'rb') as status: with open("restart.pickle", "rb") as status:
chat_id, message_id = pickle.load(status) chat_id, message_id = pickle.load(status)
os.remove("restart.pickle") os.remove("restart.pickle")
await app.edit_message_text(chat_id=chat_id, message_id=message_id, text="<b>Bot restarted successfully!</b>") await app.edit_message_text(
chat_id=chat_id,
message_id=message_id,
text="<b>Bot restarted successfully!</b>",
)
asyncio.create_task(auto_clean()) asyncio.create_task(auto_clean())
await idle() await idle()
if __name__ == "__main__": if __name__ == "__main__":
try: try:
loop.run_until_complete(start_bot()) loop.run_until_complete(start_bot())
@ -96,4 +93,6 @@ if __name__ == "__main__":
LOGGER.info(err) LOGGER.info(err)
finally: finally:
loop.stop() loop.stop()
LOGGER.info("------------------------ Stopped Services ------------------------") LOGGER.info(
"------------------------ Stopped Services ------------------------"
)

View file

@ -1,4 +1,4 @@
from .errors import * from .errors import *
from .misc import * from .misc import *
from .permissions import * from .permissions import *
from .ratelimiter import * from .ratelimiter import *

View file

@ -1,10 +1,10 @@
import asyncio import os
import traceback import traceback
from functools import wraps
from datetime import datetime from datetime import datetime
from functools import wraps
from pyrogram.errors.exceptions.flood_420 import FloodWait
from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
from pyrogram.types import CallbackQuery
from misskaty import app from misskaty import app
from misskaty.vars import LOG_CHANNEL from misskaty.vars import LOG_CHANNEL
@ -13,6 +13,14 @@ from misskaty.vars import LOG_CHANNEL
def capture_err(func): def capture_err(func):
@wraps(func) @wraps(func)
async def capture(client, message, *args, **kwargs): async def capture(client, message, *args, **kwargs):
if isinstance(message, CallbackQuery):
sender = message.message.reply
chat = message.message.chat
msg = message.message.text or message.message.caption
else:
sender = message.reply
chat = message.chat
msg = message.text or message.caption
try: try:
return await func(client, message, *args, **kwargs) return await func(client, message, *args, **kwargs)
except ChatWriteForbidden: except ChatWriteForbidden:
@ -20,23 +28,29 @@ def capture_err(func):
except Exception as err: except Exception as err:
exc = traceback.format_exc() exc = traceback.format_exc()
error_feedback = "ERROR | {} | {}\n\n{}\n\n{}\n".format( error_feedback = "ERROR | {} | {}\n\n{}\n\n{}\n".format(
message.from_user.id if message.from_user else 0, message.from_user.id if message.from_user else 0,
message.chat.id if message.chat else 0, chat.id if chat else 0,
message.text or message.caption, msg,
exc, exc,
) )
day = datetime.today() day = datetime.now()
tgl_now = datetime.now() tgl_now = datetime.now()
cap_day = f"{day.strftime('%A')}, {tgl_now.strftime('%d %B %Y %H:%M:%S')}" cap_day = f"{day.strftime('%A')}, {tgl_now.strftime('%d %B %Y %H:%M:%S')}"
await message.reply("😭 An Internal Error Occurred while processing your Command, the Logs have been sent to the Owners of this Bot. Sorry for Inconvenience...") await sender(
with open(f"crash_{tgl_now.strftime('%d %B %Y')}.log", "w+", encoding="utf-8") as log: "😭 An Internal Error Occurred while processing your Command, the Logs have been sent to the Owners of this Bot. Sorry for Inconvenience..."
)
with open(
f"crash_{tgl_now.strftime('%d %B %Y')}.txt", "w+", encoding="utf-8"
) as log:
log.write(error_feedback) log.write(error_feedback)
log.close() log.close()
await app.send_document( await app.send_document(
LOG_CHANNEL, f"crash_{tgl_now.strftime('%d %B %Y')}.log", caption=f"Crash Report of this Bot\n{cap_day}" LOG_CHANNEL,
f"crash_{tgl_now.strftime('%d %B %Y')}.txt",
caption=f"Crash Report of this Bot\n{cap_day}",
) )
os.remove(f"crash_{tgl_now.strftime('%d %B %Y')}.log") os.remove(f"crash_{tgl_now.strftime('%d %B %Y')}.txt")
raise err raise err
return capture return capture

View file

@ -1,6 +1,7 @@
import asyncio import asyncio
from functools import wraps from functools import wraps
def asyncify(func): def asyncify(func):
async def inner(*args, **kwargs): async def inner(*args, **kwargs):
loop = asyncio.get_running_loop() loop = asyncio.get_running_loop()
@ -9,6 +10,7 @@ def asyncify(func):
return inner return inner
def new_task(func): def new_task(func):
@wraps(func) @wraps(func)
def wrapper(*args, **kwargs): def wrapper(*args, **kwargs):
@ -18,4 +20,4 @@ def new_task(func):
except Exception as e: except Exception as e:
LOGGER.error(f"Failed to create task for {func.__name__} : {e}") LOGGER.error(f"Failed to create task for {func.__name__} : {e}")
return wrapper return wrapper

View file

@ -1,17 +1,22 @@
from time import time
from functools import partial, wraps from functools import partial, wraps
from typing import Union, Optional from time import time
from traceback import format_exc as err from traceback import format_exc as err
from typing import Optional, Union
from pyrogram import enums, Client from pyrogram import Client, enums
from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden from pyrogram.errors import ChannelPrivate, ChatAdminRequired, ChatWriteForbidden
from ...helper.localization import default_language, get_lang, get_locale_string, langdict from pyrogram.types import CallbackQuery, Message
from pyrogram.types import Message, CallbackQuery
from misskaty import app from misskaty import app
from misskaty.vars import SUDO from misskaty.vars import SUDO
from ...helper.localization import (
default_language,
get_lang,
get_locale_string,
langdict,
)
async def member_permissions(chat_id: int, user_id: int): async def member_permissions(chat_id: int, user_id: int):
perms = [] perms = []
@ -40,80 +45,6 @@ async def member_permissions(chat_id: int, user_id: int):
return [] return []
async def check_perms(
message: Union[CallbackQuery, Message],
permissions: Optional[Union[list, str]],
complain_missing_perms: bool,
strings,
) -> bool:
if isinstance(message, CallbackQuery):
sender = partial(message.answer, show_alert=True)
chat = message.message.chat
else:
sender = message.reply_text
chat = message.chat
# TODO: Cache all admin permissions in db.
user = await chat.get_member(message.from_user.id)
if user.status == enums.ChatMemberStatus.OWNER:
return True
# No permissions specified, accept being an admin.
if not permissions and user.status == enums.ChatMemberStatus.ADMINISTRATOR:
return True
if user.status != enums.ChatMemberStatus.ADMINISTRATOR:
if complain_missing_perms:
await sender(strings("no_admin_error"))
return False
if isinstance(permissions, str):
permissions = [permissions]
missing_perms = [permission for permission in permissions if not getattr(user.privileges, permission)]
if not missing_perms:
return True
if complain_missing_perms:
await sender(strings("no_permission_error").format(permissions=", ".join(missing_perms)))
return False
async def check_perms(
message: Union[CallbackQuery, Message],
permissions: Optional[Union[list, str]],
complain_missing_perms: bool,
strings,
) -> bool:
if isinstance(message, CallbackQuery):
sender = partial(message.answer, show_alert=True)
chat = message.message.chat
else:
sender = message.reply_text
chat = message.chat
# TODO: Cache all admin permissions in db.
user = await chat.get_member(message.from_user.id)
if user.status == enums.ChatMemberStatus.OWNER:
return True
# No permissions specified, accept being an admin.
if not permissions and user.status == enums.ChatMemberStatus.ADMINISTRATOR:
return True
if user.status != enums.ChatMemberStatus.ADMINISTRATOR:
if complain_missing_perms:
await sender(strings("no_admin_error"))
return False
if isinstance(permissions, str):
permissions = [permissions]
missing_perms = [permission for permission in permissions if not getattr(user.privileges, permission)]
if not missing_perms:
return True
if complain_missing_perms:
await sender(strings("no_permission_error").format(permissions=", ".join(missing_perms)))
return False
async def check_perms( async def check_perms(
message: Union[CallbackQuery, Message], message: Union[CallbackQuery, Message],
permissions: Optional[Union[list, str]], permissions: Optional[Union[list, str]],
@ -128,7 +59,10 @@ async def check_perms(
chat = message.chat chat = message.chat
if not message.from_user: if not message.from_user:
return bool(message.sender_chat and message.sender_chat.id == message.chat.id) return bool(message.sender_chat and message.sender_chat.id == message.chat.id)
user = await chat.get_member(message.from_user.id) try:
user = await chat.get_member(message.from_user.id)
except ChatAdminRequired:
return False
if user.status == enums.ChatMemberStatus.OWNER: if user.status == enums.ChatMemberStatus.OWNER:
return True return True
@ -156,17 +90,19 @@ admins_in_chat = {}
async def list_admins(chat_id: int): async def list_admins(chat_id: int):
global admins_in_chat
if chat_id in admins_in_chat: if chat_id in admins_in_chat:
interval = time() - admins_in_chat[chat_id]["last_updated_at"] interval = time() - admins_in_chat[chat_id]["last_updated_at"]
if interval < 3600: if interval < 3600:
return admins_in_chat[chat_id]["data"] return admins_in_chat[chat_id]["data"]
admins_in_chat[chat_id] = { try:
"last_updated_at": time(), admins_in_chat[chat_id] = {
"data": [member.user.id async for member in app.get_chat_members(chat_id, filter=enums.ChatMembersFilter.ADMINISTRATORS)], "last_updated_at": time(),
} "data": [member.user.id async for member in app.get_chat_members(chat_id, filter=enums.ChatMembersFilter.ADMINISTRATORS)],
return admins_in_chat[chat_id]["data"] }
return admins_in_chat[chat_id]["data"]
except ChannelPrivate:
return
async def authorised(func, subFunc2, client, message, *args, **kwargs): async def authorised(func, subFunc2, client, message, *args, **kwargs):

View file

@ -1,6 +1,7 @@
from pyrogram import filters
import asyncio import asyncio
from pyrogram import filters
data = {} data = {}
@ -13,7 +14,10 @@ async def task(msg, warn=False, sec=None):
user = msg.from_user user = msg.from_user
ids = await msg.reply_msg(f"Sorry {user.mention} [<code>{user.id}</code>], you must wait for {sec}s before using command again..") ids = await msg.reply_msg(f"Sorry {user.mention} [<code>{user.id}</code>], you must wait for {sec}s before using command again..")
await asyncio.sleep(sec) await asyncio.sleep(sec)
await ids.edit_msg(f"Alright {user.mention} [<code>{user.id}</code>], your cooldown is over you can command again.", del_in=3) await ids.edit_msg(
f"Alright {user.mention} [<code>{user.id}</code>], your cooldown is over you can command again.",
del_in=3,
)
def wait(sec): def wait(sec):

View file

@ -1,10 +1,12 @@
from cachetools import TTLCache
from functools import wraps from functools import wraps
from ..ratelimiter_func import RateLimiter
from typing import Callable, Union from typing import Callable, Union
from cachetools import TTLCache
from pyrogram import Client from pyrogram import Client
from pyrogram.types import CallbackQuery, Message
from pyrogram.errors import QueryIdInvalid from pyrogram.errors import QueryIdInvalid
from pyrogram.types import CallbackQuery, Message
from ..ratelimiter_func import RateLimiter
ratelimit = RateLimiter() ratelimit = RateLimiter()
# storing spammy user in cache for 1minute before allowing them to use commands again. # storing spammy user in cache for 1minute before allowing them to use commands again.

View file

@ -1,7 +1,15 @@
import asyncio import asyncio
from logging import getLogger from logging import getLogger
from pyrogram.errors import ChatWriteForbidden, FloodWait, MessageNotModified, ChatAdminRequired, MessageDeleteForbidden, MessageIdInvalid, MessageEmpty from pyrogram.errors import (
ChatAdminRequired,
ChatWriteForbidden,
FloodWait,
MessageDeleteForbidden,
MessageEmpty,
MessageIdInvalid,
MessageNotModified,
)
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)

View file

@ -1 +1 @@
from . import bound, methods, listen from . import bound, listen, methods

View file

@ -1,11 +1,22 @@
import io
import html import html
import io
from asyncio import get_event_loop
from asyncio import sleep as asleep
from logging import getLogger from logging import getLogger
from pyrogram.types import Message
from pyrogram.errors import MessageNotModified, MessageAuthorRequired, MessageIdInvalid, ChatWriteForbidden, ChatAdminRequired, FloodWait, MessageTooLong, MessageDeleteForbidden
from asyncio import sleep as asleep, get_event_loop
from typing import Union from typing import Union
from pyrogram.errors import (
ChatAdminRequired,
ChatWriteForbidden,
FloodWait,
MessageAuthorRequired,
MessageDeleteForbidden,
MessageIdInvalid,
MessageNotModified,
MessageTooLong,
)
from pyrogram.types import Message
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
Message.input = property(lambda m: m.text[m.text.find(m.command[0]) + len(m.command[0]) + 1 :] if len(m.command) > 1 else None) Message.input = property(lambda m: m.text[m.text.find(m.command[0]) + len(m.command[0]) + 1 :] if len(m.command) > 1 else None)
@ -223,7 +234,13 @@ async def reply_or_send_as_file(self, text: str, as_raw: bool = False, del_in: i
return await reply_as_file(self, text=text, **kwargs) return await reply_as_file(self, text=text, **kwargs)
async def reply_as_file(self, text: str, filename: str = "output.txt", caption: str = "", delete_message: bool = True): async def reply_as_file(
self,
text: str,
filename: str = "output.txt",
caption: str = "",
delete_message: bool = True,
):
"""\nYou can send large outputs as file """\nYou can send large outputs as file
Example: Example:
message.reply_as_file(text="hello") message.reply_as_file(text="hello")
@ -245,7 +262,12 @@ async def reply_as_file(self, text: str, filename: str = "output.txt", caption:
get_event_loop().create_task(self.delete()) get_event_loop().create_task(self.delete())
doc = io.BytesIO(text.encode()) doc = io.BytesIO(text.encode())
doc.name = filename doc.name = filename
return await self.reply_document(document=doc, caption=caption[:1024], disable_notification=True, reply_to_message_id=reply_to_id) return await self.reply_document(
document=doc,
caption=caption[:1024],
disable_notification=True,
reply_to_message_id=reply_to_id,
)
async def delete(self, revoke: bool = True) -> bool: async def delete(self, revoke: bool = True) -> bool:

View file

@ -1 +1 @@
from .listen import Client, MessageHandler, Chat, User from .listen import Chat, Client, MessageHandler, User

View file

@ -1,28 +1,34 @@
""" """
pyromod - A monkeypatcher add-on for Pyrogram pyromod - A monkeypatcher add-on for Pyrogram
Copyright (C) 2020 Cezar H. <https://github.com/usernein> Copyright (C) 2020 Cezar H. <https://github.com/usernein>
This file is part of pyromod. This file is part of pyromod.
pyromod is free software: you can redistribute it and/or modify pyromod is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
pyromod is distributed in the hope that it will be useful, pyromod is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>. along with pyromod. If not, see <https://www.gnu.org/licenses/>.
""" """
import asyncio import asyncio
import logging
from enum import Enum
from inspect import iscoroutinefunction
from typing import Callable, Optional, Union
import pyrogram import pyrogram
from inspect import iscoroutinefunction from ..utils import PyromodConfig, patch, patchable
from typing import Optional, Callable, Union
from pyrogram.errors import QueryIdInvalid
from enum import Enum
from ..utils import patch, patchable, PyromodConfig logger = logging.getLogger(__name__)
class ListenerStopped(Exception): class ListenerStopped(Exception):
@ -40,12 +46,12 @@ class ListenerTypes(Enum):
@patch(pyrogram.client.Client) @patch(pyrogram.client.Client)
class Client: class Client:
@patchable @patchable()
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
self.listeners = {listener_type: {} for listener_type in ListenerTypes} self.listeners = {listener_type: {} for listener_type in ListenerTypes}
self.old__init__(*args, **kwargs) self.old__init__(*args, **kwargs)
@patchable @patchable()
async def listen( async def listen(
self, self,
identifier: tuple, identifier: tuple,
@ -55,10 +61,15 @@ class Client:
unallowed_click_alert=True, unallowed_click_alert=True,
): ):
if type(listener_type) != ListenerTypes: if type(listener_type) != ListenerTypes:
raise TypeError("Parameter listener_type should be a" " value from pyromod.listen.ListenerTypes") raise TypeError(
"Parameter listener_type should be a"
" value from pyromod.listen.ListenerTypes"
)
future = self.loop.create_future() future = self.loop.create_future()
future.add_done_callback(lambda f: self.stop_listening(identifier, listener_type)) future.add_done_callback(
lambda f: self.stop_listening(identifier, listener_type)
)
listener_data = { listener_data = {
"future": future, "future": future,
@ -76,7 +87,7 @@ class Client:
elif PyromodConfig.throw_exceptions: elif PyromodConfig.throw_exceptions:
raise ListenerTimeout(timeout) raise ListenerTimeout(timeout)
@patchable @patchable()
async def ask( async def ask(
self, self,
text, text,
@ -99,7 +110,7 @@ class Client:
user_id is null, and to take precedence user_id is null, and to take precedence
""" """
@patchable @patchable()
def match_listener( def match_listener(
self, self,
data: Optional[tuple] = None, data: Optional[tuple] = None,
@ -147,14 +158,16 @@ class Client:
return listener, identifier return listener, identifier
return None, None return None, None
@patchable @patchable()
def stop_listening( def stop_listening(
self, self,
data: Optional[tuple] = None, data: Optional[tuple] = None,
listener_type: ListenerTypes = ListenerTypes.MESSAGE, listener_type: ListenerTypes = ListenerTypes.MESSAGE,
identifier_pattern: Optional[tuple] = None, identifier_pattern: Optional[tuple] = None,
): ):
listener, identifier = self.match_listener(data, listener_type, identifier_pattern) listener, identifier = self.match_listener(
data, listener_type, identifier_pattern
)
if not listener: if not listener:
return return
@ -172,19 +185,23 @@ class Client:
@patch(pyrogram.handlers.message_handler.MessageHandler) @patch(pyrogram.handlers.message_handler.MessageHandler)
class MessageHandler: class MessageHandler:
@patchable @patchable()
def __init__(self, callback: Callable, filters=None): def __init__(self, callback: Callable, filters=None):
self.registered_handler = callback self.registered_handler = callback
self.old__init__(self.resolve_future, filters) self.old__init__(self.resolve_future, filters)
@patchable @patchable()
async def check(self, client, message): async def check(self, client, message):
if user := getattr(message, "from_user", None): if user := getattr(message, "from_user", None):
user = user.id user = user.id
listener = client.match_listener( try:
(message.chat.id, user, message.id), listener = client.match_listener(
ListenerTypes.MESSAGE, (message.chat.id, user, message.id),
)[0] ListenerTypes.MESSAGE,
)[0]
except AttributeError as err:
logger.warning(f"Get : {err}\n\n{message}")
raise err
listener_does_match = handler_does_match = False listener_does_match = handler_does_match = False
@ -194,7 +211,9 @@ class MessageHandler:
if iscoroutinefunction(filters.__call__): if iscoroutinefunction(filters.__call__):
listener_does_match = await filters(client, message) listener_does_match = await filters(client, message)
else: else:
listener_does_match = await client.loop.run_in_executor(None, filters, client, message) listener_does_match = await client.loop.run_in_executor(
None, filters, client, message
)
else: else:
listener_does_match = True listener_does_match = True
@ -202,7 +221,9 @@ class MessageHandler:
if iscoroutinefunction(self.filters.__call__): if iscoroutinefunction(self.filters.__call__):
handler_does_match = await self.filters(client, message) handler_does_match = await self.filters(client, message)
else: else:
handler_does_match = await client.loop.run_in_executor(None, self.filters, client, message) handler_does_match = await client.loop.run_in_executor(
None, self.filters, client, message
)
else: else:
handler_does_match = True handler_does_match = True
@ -210,7 +231,7 @@ class MessageHandler:
# exists but its filters doesn't match # exists but its filters doesn't match
return listener_does_match or handler_does_match return listener_does_match or handler_does_match
@patchable @patchable()
async def resolve_future(self, client, message, *args): async def resolve_future(self, client, message, *args):
listener_type = ListenerTypes.MESSAGE listener_type = ListenerTypes.MESSAGE
if user := getattr(message, "from_user", None): if user := getattr(message, "from_user", None):
@ -226,7 +247,9 @@ class MessageHandler:
if iscoroutinefunction(filters.__call__): if iscoroutinefunction(filters.__call__):
listener_does_match = await filters(client, message) listener_does_match = await filters(client, message)
else: else:
listener_does_match = await client.loop.run_in_executor(None, filters, client, message) listener_does_match = await client.loop.run_in_executor(
None, filters, client, message
)
else: else:
listener_does_match = True listener_does_match = True
@ -241,20 +264,24 @@ class MessageHandler:
@patch(pyrogram.handlers.callback_query_handler.CallbackQueryHandler) @patch(pyrogram.handlers.callback_query_handler.CallbackQueryHandler)
class CallbackQueryHandler: class CallbackQueryHandler:
@patchable @patchable()
def __init__(self, callback: Callable, filters=None): def __init__(self, callback: Callable, filters=None):
self.registered_handler = callback self.registered_handler = callback
self.old__init__(self.resolve_future, filters) self.old__init__(self.resolve_future, filters)
@patchable @patchable()
async def check(self, client, query): async def check(self, client, query):
chatID, mID = None, None chatID, mID = None, None
if message := getattr(query, "message", None): if message := getattr(query, "message", None):
chatID, mID = message.chat.id, message.id chatID, mID = message.chat.id, message.id
listener = client.match_listener( try:
(chatID, query.from_user.id, mID), listener = client.match_listener(
ListenerTypes.CALLBACK_QUERY, (chatID, query.from_user.id, mID),
)[0] ListenerTypes.CALLBACK_QUERY,
)[0]
except AttributeError as err:
logger.warning(f"Get : {err}\n\n{message}")
raise err
# managing unallowed user clicks # managing unallowed user clicks
if PyromodConfig.unallowed_click_alert: if PyromodConfig.unallowed_click_alert:
@ -267,12 +294,15 @@ class CallbackQueryHandler:
listener_type=ListenerTypes.CALLBACK_QUERY, listener_type=ListenerTypes.CALLBACK_QUERY,
)[0] )[0]
if (permissive_listener and not listener) and permissive_listener["unallowed_click_alert"]: if (permissive_listener and not listener) and permissive_listener[
alert = permissive_listener["unallowed_click_alert"] if type(permissive_listener["unallowed_click_alert"]) == str else PyromodConfig.unallowed_click_alert_text "unallowed_click_alert"
try: ]:
await query.answer(alert) alert = (
except QueryIdInvalid: permissive_listener["unallowed_click_alert"]
return False if type(permissive_listener["unallowed_click_alert"]) is str
else PyromodConfig.unallowed_click_alert_text
)
await query.answer(alert)
return False return False
filters = listener["filters"] if listener else self.filters filters = listener["filters"] if listener else self.filters
@ -285,7 +315,7 @@ class CallbackQueryHandler:
else: else:
return True return True
@patchable @patchable()
async def resolve_future(self, client, query, *args): async def resolve_future(self, client, query, *args):
listener_type = ListenerTypes.CALLBACK_QUERY listener_type = ListenerTypes.CALLBACK_QUERY
chatID, mID = None, None chatID, mID = None, None
@ -305,7 +335,7 @@ class CallbackQueryHandler:
@patch(pyrogram.types.messages_and_media.message.Message) @patch(pyrogram.types.messages_and_media.message.Message)
class Message(pyrogram.types.messages_and_media.message.Message): class Message(pyrogram.types.messages_and_media.message.Message):
@patchable @patchable()
async def wait_for_click( async def wait_for_click(
self, self,
from_user_id: Optional[int] = None, from_user_id: Optional[int] = None,
@ -324,29 +354,33 @@ class Message(pyrogram.types.messages_and_media.message.Message):
@patch(pyrogram.types.user_and_chats.chat.Chat) @patch(pyrogram.types.user_and_chats.chat.Chat)
class Chat(pyrogram.types.Chat): class Chat(pyrogram.types.Chat):
@patchable @patchable()
def listen(self, *args, **kwargs): def listen(self, *args, **kwargs):
return self._client.listen((self.id, None, None), *args, **kwargs) return self._client.listen((self.id, None, None), *args, **kwargs)
@patchable @patchable()
def ask(self, text, *args, **kwargs): def ask(self, text, *args, **kwargs):
return self._client.ask(text, (self.id, None, None), *args, **kwargs) return self._client.ask(text, (self.id, None, None), *args, **kwargs)
@patchable @patchable()
def stop_listening(self, *args, **kwargs): def stop_listening(self, *args, **kwargs):
return self._client.stop_listening(*args, identifier_pattern=(self.id, None, None), **kwargs) return self._client.stop_listening(
*args, identifier_pattern=(self.id, None, None), **kwargs
)
@patch(pyrogram.types.user_and_chats.user.User) @patch(pyrogram.types.user_and_chats.user.User)
class User(pyrogram.types.User): class User(pyrogram.types.User):
@patchable @patchable()
def listen(self, *args, **kwargs): def listen(self, *args, **kwargs):
return self._client.listen((None, self.id, None), *args, **kwargs) return self._client.listen((None, self.id, None), *args, **kwargs)
@patchable @patchable()
def ask(self, text, *args, **kwargs): def ask(self, text, *args, **kwargs):
return self._client.ask(text, (self.id, self.id, None), *args, **kwargs) return self._client.ask(text, (self.id, self.id, None), *args, **kwargs)
@patchable @patchable()
def stop_listening(self, *args, **kwargs): def stop_listening(self, *args, **kwargs):
return self._client.stop_listening(*args, identifier_pattern=(None, self.id, None), **kwargs) return self._client.stop_listening(
*args, identifier_pattern=(None, self.id, None), **kwargs
)

View file

@ -1,3 +1,3 @@
from .send_message import send_message
from .edit_message_text import edit_message_text from .edit_message_text import edit_message_text
from .send_as_file import send_as_file from .send_as_file import send_as_file
from .send_message import send_message

View file

@ -1,10 +1,18 @@
from typing import Union
import asyncio import asyncio
from typing import Union
from pyrogram import Client from pyrogram import Client
from pyrogram.types import Message
async def edit_message_text(self, chat_id: Union[int, str], message_id: int, text: str, del_in: int = 0, *args, **kwargs) -> Union["Message", bool]: async def edit_message_text(
self,
chat_id: Union[int, str],
message_id: int,
text: str,
del_in: int = 0,
*args,
**kwargs
) -> Union["Message", bool]:
"""\nExample: """\nExample:
message.edit_text("hello") message.edit_text("hello")
Parameters: Parameters:
@ -41,7 +49,9 @@ async def edit_message_text(self, chat_id: Union[int, str], message_id: int, tex
Raises: Raises:
RPCError: In case of a Telegram RPC error. RPCError: In case of a Telegram RPC error.
""" """
msg = await self.edit_message_text(chat_id=chat_id, message_id=message_id, text=text, *args, **kwargs) msg = await self.edit_message_text(
chat_id=chat_id, message_id=message_id, text=text, *args, **kwargs
)
if del_in == 0: if del_in == 0:
return msg return msg
await asyncio.sleep(del_in) await asyncio.sleep(del_in)

View file

@ -1,10 +1,18 @@
import io import io
from typing import Union, Optional from typing import Optional, Union
from pyrogram.types import Message
from pyrogram import Client from pyrogram import Client
async def send_as_file(self, chat_id: Union[int, str], text: str, filename: str = "output.txt", caption: str = "", log: Union[bool, str] = False, reply_to_message_id: Optional[int] = None) -> "Message": async def send_as_file(
self,
chat_id: Union[int, str],
text: str,
filename: str = "output.txt",
caption: str = "",
log: Union[bool, str] = False,
reply_to_message_id: Optional[int] = None,
) -> "Message":
"""\nYou can send large outputs as file """\nYou can send large outputs as file
Example: Example:
@userge.send_as_file(chat_id=12345, text="hello") @userge.send_as_file(chat_id=12345, text="hello")
@ -33,7 +41,13 @@ async def send_as_file(self, chat_id: Union[int, str], text: str, filename: str
doc = io.BytesIO(text.encode()) doc = io.BytesIO(text.encode())
doc.name = filename doc.name = filename
return await self.send_document(chat_id=chat_id, document=doc, caption=caption[:1024], disable_notification=True, reply_to_message_id=reply_to_message_id) return await self.send_document(
chat_id=chat_id,
document=doc,
caption=caption[:1024],
disable_notification=True,
reply_to_message_id=reply_to_message_id,
)
Client.send_as_file = send_as_file Client.send_as_file = send_as_file

View file

@ -1,10 +1,12 @@
from typing import Union
from pyrogram.types import Message
from pyrogram import Client
import asyncio import asyncio
from typing import Union
from pyrogram import Client
async def send_message(self, chat_id: Union[int, str], text: str, del_in: int = 0, *args, **kwargs) -> Union["Message", bool]: async def send_message(
self, chat_id: Union[int, str], text: str, del_in: int = 0, *args, **kwargs
) -> Union["Message", bool]:
"""\nSend text messages. """\nSend text messages.
Example: Example:
@userge.send_message(chat_id=12345, text='test') @userge.send_message(chat_id=12345, text='test')

View file

@ -1 +1 @@
from .utils import patch, patchable, PyromodConfig from .utils import PyromodConfig, patch, patchable

View file

@ -17,6 +17,14 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with pyromod. If not, see <https://www.gnu.org/licenses/>. along with pyromod. If not, see <https://www.gnu.org/licenses/>.
""" """
from contextlib import asynccontextmanager, contextmanager
from inspect import iscoroutinefunction
from logging import getLogger
from typing import Callable
from pyrogram.sync import async_to_sync
logger = getLogger(__name__)
class PyromodConfig: class PyromodConfig:
@ -24,7 +32,7 @@ class PyromodConfig:
stopped_handler = None stopped_handler = None
throw_exceptions = True throw_exceptions = True
unallowed_click_alert = True unallowed_click_alert = True
unallowed_click_alert_text = "[misskaty] You're not authorized to click this button." unallowed_click_alert_text = "[pyromod] You're not expected to click this button."
def patch(obj): def patch(obj):
@ -36,12 +44,80 @@ def patch(obj):
old = getattr(obj, name, None) old = getattr(obj, name, None)
if old is not None: # Not adding 'old' to new func if old is not None: # Not adding 'old' to new func
setattr(obj, f"old{name}", old) setattr(obj, f"old{name}", old)
# Worse Code
tempConf = {
i: getattr(func, i, False)
for i in ["is_property", "is_static", "is_context"]
}
async_to_sync(container, name)
func = getattr(container, name)
for tKey, tValue in tempConf.items():
setattr(func, tKey, tValue)
if func.is_property:
func = property(func)
elif func.is_static:
func = staticmethod(func)
elif func.is_context:
if iscoroutinefunction(func.__call__):
func = asynccontextmanager(func)
else:
func = contextmanager(func)
logger.info(
f"Patch Attribute To {obj.__name__} From {container.__name__} : {name}"
)
setattr(obj, name, func) setattr(obj, name, func)
return container return container
return wrapper return wrapper
def patchable(func): def patchable(
func.patchable = True is_property: bool = False, is_static: bool = False, is_context: bool = False
return func ) -> Callable:
"""
A decorator that marks a function as patchable.
Usage:
@patchable(is_property=True)
def my_property():
...
@patchable(is_static=True)
def my_static_method():
...
@patchable(is_context=True)
def my_context_manager():
...
@patchable(is_property=False, is_static=False, is_context=False)
def my_function():
...
@patchable()
def default_usage():
...
Parameters:
- is_property (bool): whether the function is a property. Default is False.
- is_static (bool): whether the function is a static method. Default is False.
- is_context (bool): whether the function is a context manager. Default is False.
Returns:
- A callable object that marks the function as patchable.
"""
def wrapper(func: Callable) -> Callable:
func.patchable = True
func.is_property = is_property
func.is_static = is_static
func.is_context = is_context
return func
return wrapper

View file

@ -1,6 +1,12 @@
from typing import Union from typing import Union
from pyrate_limiter import BucketFullException, Duration, Limiter, MemoryListBucket, RequestRate from pyrate_limiter import (
BucketFullException,
Duration,
Limiter,
MemoryListBucket,
RequestRate,
)
class RateLimiter: class RateLimiter:
@ -11,17 +17,17 @@ class RateLimiter:
""" """
def __init__(self) -> None: def __init__(self) -> None:
# 2 requests per seconds # 1 requests per seconds
self.second_rate = RequestRate(2, Duration.SECOND) self.second_rate = RequestRate(1, Duration.SECOND)
# 15 requests per minute. # 15 requests per minute.
self.minute_rate = RequestRate(15, Duration.MINUTE) self.minute_rate = RequestRate(15, Duration.MINUTE)
# 500 requests per hour # 100 requests per hour
self.hourly_rate = RequestRate(500, Duration.HOUR) self.hourly_rate = RequestRate(100, Duration.HOUR)
# 1500 requests per day # 500 requests per day
self.daily_rate = RequestRate(1500, Duration.DAY) self.daily_rate = RequestRate(500, Duration.DAY)
self.limiter = Limiter( self.limiter = Limiter(
self.minute_rate, self.minute_rate,

View file

@ -8,7 +8,7 @@ from .media_helper import *
from .misc import * from .misc import *
from .pyro_progress import * from .pyro_progress import *
from .stickerset import * from .stickerset import *
from .subscene_helper import *
from .time_gap import * from .time_gap import *
from .tools import * from .tools import *
from .ytdl_helper import * from .ytdl_helper import *
from .subscene_helper import *

View file

@ -46,7 +46,20 @@ async def meval(code, globs, **kwargs):
if not any(isinstance(node, ast.Return) for node in code): if not any(isinstance(node, ast.Return) for node in code):
for i in range(len(code)): for i in range(len(code)):
if isinstance(code[i], ast.Expr) and (i == len(code) - 1 or not isinstance(code[i].value, ast.Call)): if isinstance(code[i], ast.Expr) and (i == len(code) - 1 or not isinstance(code[i].value, ast.Call)):
code[i] = ast.copy_location(ast.Expr(ast.Call(func=ast.Attribute(value=ast.Name(id=ret_name, ctx=ast.Load()), attr="append", ctx=ast.Load()), args=[code[i].value], keywords=[])), code[-1]) code[i] = ast.copy_location(
ast.Expr(
ast.Call(
func=ast.Attribute(
value=ast.Name(id=ret_name, ctx=ast.Load()),
attr="append",
ctx=ast.Load(),
),
args=[code[i].value],
keywords=[],
)
),
code[-1],
)
else: else:
for node in code: for node in code:
if isinstance(node, ast.Return): if isinstance(node, ast.Return):
@ -56,11 +69,22 @@ async def meval(code, globs, **kwargs):
# globals().update(**<global_args>) # globals().update(**<global_args>)
glob_copy = ast.Expr( glob_copy = ast.Expr(
ast.Call(func=ast.Attribute(value=ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]), attr="update", ctx=ast.Load()), args=[], keywords=[ast.keyword(arg=None, value=ast.Name(id=global_args, ctx=ast.Load()))]) ast.Call(
func=ast.Attribute(
value=ast.Call(func=ast.Name(id="globals", ctx=ast.Load()), args=[], keywords=[]),
attr="update",
ctx=ast.Load(),
),
args=[],
keywords=[ast.keyword(arg=None, value=ast.Name(id=global_args, ctx=ast.Load()))],
)
) )
ast.fix_missing_locations(glob_copy) ast.fix_missing_locations(glob_copy)
code.insert(0, glob_copy) code.insert(0, glob_copy)
ret_decl = ast.Assign(targets=[ast.Name(id=ret_name, ctx=ast.Store())], value=ast.List(elts=[], ctx=ast.Load())) ret_decl = ast.Assign(
targets=[ast.Name(id=ret_name, ctx=ast.Store())],
value=ast.List(elts=[], ctx=ast.Load()),
)
ast.fix_missing_locations(ret_decl) ast.fix_missing_locations(ret_decl)
code.insert(1, ret_decl) code.insert(1, ret_decl)
args = [] args = []

View file

@ -6,7 +6,6 @@ from pyrogram.errors import FloodWait
from pyrogram.types import InputMediaPhoto from pyrogram.types import InputMediaPhoto
from misskaty.plugins.dev import shell_exec from misskaty.plugins.dev import shell_exec
from misskaty.vars import VCSI_NAME, FF_MPEG_NAME
def hhmmss(seconds): def hhmmss(seconds):
@ -15,7 +14,7 @@ def hhmmss(seconds):
async def take_ss(video_file): async def take_ss(video_file):
out_put_file_name = f"genss{str(time.time())}.png" out_put_file_name = f"genss{str(time.time())}.png"
cmd = f"{VCSI_NAME} '{video_file}' -t -w 1340 -g 4x4 --ffmpeg-name {FF_MPEG_NAME} --template misskaty/helper/ssgen_template.html --quality 100 --end-delay-percent 20 --metadata-font-size 30 --timestamp-font-size 20 -o {out_put_file_name}" cmd = f"vcsi '{video_file}' -t -w 1340 -g 4x4 --template misskaty/helper/ssgen_template.html --quality 100 --end-delay-percent 20 --metadata-font-size 30 --timestamp-font-size 20 -o {out_put_file_name}"
await shell_exec(cmd) await shell_exec(cmd)
return out_put_file_name if os.path.lexists(out_put_file_name) else None return out_put_file_name if os.path.lexists(out_put_file_name) else None
@ -23,7 +22,7 @@ async def take_ss(video_file):
async def ssgen_link(video, output_directory, ttl): async def ssgen_link(video, output_directory, ttl):
out_put_file_name = f"{output_directory}/{str(time.time())}.png" out_put_file_name = f"{output_directory}/{str(time.time())}.png"
cmd = [ cmd = [
FF_MPEG_NAME, "ffmpeg",
"-ss", "-ss",
str(ttl), str(ttl),
"-i", "-i",

View file

@ -34,11 +34,7 @@ def get_readable_time(seconds: int) -> str:
def get_readable_bitrate(bitrate_kbps): def get_readable_bitrate(bitrate_kbps):
return ( return f"{str(round(bitrate_kbps / 1000, 2))} Mb/s" if bitrate_kbps > 10000 else f"{str(round(bitrate_kbps, 2))} kb/s"
f"{str(round(bitrate_kbps / 1000, 2))} Mb/s"
if bitrate_kbps > 10000
else f"{str(round(bitrate_kbps, 2))} kb/s"
)
def get_readable_time2(seconds: int) -> str: def get_readable_time2(seconds: int) -> str:

View file

@ -1,16 +1,20 @@
import re
import traceback
import chevron
import logging import logging
import traceback
from html import escape from html import escape
from telegraph.aio import Telegraph
from misskaty.helper.http import http import chevron
from misskaty import BOT_USERNAME
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from telegraph.aio import Telegraph
from misskaty import BOT_USERNAME
from misskaty.helper.http import http
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
headers = {"Accept": "*/*", "User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"} headers = {
"Accept": "*/*",
"User-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582",
}
async def kusonimeBypass(url: str, slug=None): async def kusonimeBypass(url: str, slug=None):
@ -24,25 +28,89 @@ async def kusonimeBypass(url: str, slug=None):
soup = BeautifulSoup(page.text, "lxml") soup = BeautifulSoup(page.text, "lxml")
thumb = soup.find("div", {"class": "post-thumb"}).find("img").get("src") thumb = soup.find("div", {"class": "post-thumb"}).find("img").get("src")
data = [] data = []
# title = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > p:nth-child(3) > strong")[0].text.strip()
try: try:
title = soup.find("h1", {"class": "jdlz"}).text # fix title njing haha title = soup.find("h1", {"class": "jdlz"}).text # fix title njing haha
season = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(3)")[0].text.split(":").pop().strip() season = (
tipe = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(5)")[0].text.split(":").pop().strip() soup.select(
status_anime = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(6)")[0].text.split(":").pop().strip() "#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(3)"
ep = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(7)")[0].text.split(":").pop().strip() )[0]
score = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(8)")[0].text.split(":").pop().strip() .text.split(":")
duration = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(9)")[0].text.split(":").pop().strip() .pop()
rilis = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(10)")[0].text.split(":").pop().strip() .strip()
)
tipe = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(5)"
)[0]
.text.split(":")
.pop()
.strip()
)
status_anime = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(6)"
)[0]
.text.split(":")
.pop()
.strip()
)
ep = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(7)"
)[0]
.text.split(":")
.pop()
.strip()
)
score = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(8)"
)[0]
.text.split(":")
.pop()
.strip()
)
duration = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(9)"
)[0]
.text.split(":")
.pop()
.strip()
)
rilis = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(10)"
)[0]
.text.split(":")
.pop()
.strip()
)
except Exception: except Exception:
e = traceback.format_exc() e = traceback.format_exc()
LOGGER.error(e) LOGGER.error(e)
title, season, tipe, status_anime, ep, score, duration, rilis = "None", "None", "None", "None", 0, 0, 0, "None" title, season, tipe, status_anime, ep, score, duration, rilis = (
"None",
"None",
"None",
"None",
0,
0,
0,
"None",
)
genre = [] genre = []
for _genre in soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(2)"): for _genre in soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(2)"
):
gen = _genre.text.split(":").pop().strip().split(", ") gen = _genre.text.split(":").pop().strip().split(", ")
genre = gen genre = gen
for num, smokedl in enumerate(soup.find("div", {"class": "dlbodz"}).find_all("div", {"class": "smokeddlrh"}), start=1): for num, smokedl in enumerate(
soup.find("div", {"class": "dlbodz"}).find_all(
"div", {"class": "smokeddlrh"}
),
start=1,
):
mendata = {"name": title, "links": []} mendata = {"name": title, "links": []}
for smokeurl in smokedl.find_all("div", {"class": "smokeurlrh"}): for smokeurl in smokedl.find_all("div", {"class": "smokeurlrh"}):
quality = smokeurl.find("strong").text quality = smokeurl.find("strong").text
@ -109,7 +177,9 @@ async def byPassPh(url: str, name: str):
telegraph = Telegraph() telegraph = Telegraph()
if not telegraph.get_access_token(): if not telegraph.get_access_token():
await telegraph.create_account(short_name=BOT_USERNAME) await telegraph.create_account(short_name=BOT_USERNAME)
page = await telegraph.create_page(f"{kusonime.get('title')} By {escape(name)}", html_content=html) page = await telegraph.create_page(
f"{kusonime.get('title')} By {escape(name)}", html_content=html
)
results |= {"error": False, "url": f'https://telegra.ph/{page["path"]}'} results |= {"error": False, "url": f'https://telegra.ph/{page["path"]}'}
del results["error_message"] del results["error_message"]
return results return results
@ -117,10 +187,12 @@ async def byPassPh(url: str, name: str):
class Kusonime: class Kusonime:
def __init__(self): def __init__(self):
pass raise NotImplementedError()
async def byPass(self, url): @staticmethod
async def byPass(url):
return await kusonimeBypass(url) return await kusonimeBypass(url)
async def telegraph(self, url, name): @staticmethod
async def telegraph(url, name):
return await byPassPh(url, name) return await byPassPh(url, name)

View file

@ -13,30 +13,8 @@ from database.locale_db import get_db_lang
enabled_locales: List[str] = [ enabled_locales: List[str] = [
# "en-GB", # English (United Kingdom) # "en-GB", # English (United Kingdom)
"en-US", # English (United States) "en-US", # English (United States)
# "pt-BR", # Portuguese (Brazil)
# "es-ES", # Spanish
# "fr-FR", # French
# "de-DE", # German
# "it-IT", # Italian
# "nl-NL", # Dutch
# "ar-SA", # Arabic
# "ckb-IR", # Sorani (Kurdish)
# "fi-FI", # Finnish
# "he-IL", # Hebrew
"id-ID", # Indonesian "id-ID", # Indonesian
"id-JW", # Javanese "id-JW", # Javanese
# "ja-JP", # Japanese
# "no-NO", # Norwegian
# "pl-PL", # Polish
# "pt-BRe", # Portuguese (Brazil, extended version)
# "pt-BR2", # Portuguese (Brazil, informal version)
# "ro-RO", # Romanian
# "ru-RU", # Russian
# "sv-SE", # Swedish
# "tr-TR", # Turkish
# "uk-UA", # Ukranian
# "zh-CN", # Chinese (Simplified)
# "zh-TW", # Chinese (Traditional)
] ]
default_language: str = "en-US" default_language: str = "en-US"

View file

@ -3,9 +3,10 @@ import os
import shlex import shlex
from typing import Tuple from typing import Tuple
from misskaty import BOT_USERNAME
from telegraph.aio import Telegraph from telegraph.aio import Telegraph
from misskaty import BOT_USERNAME
async def post_to_telegraph(is_media: bool, title=None, content=None, media=None): async def post_to_telegraph(is_media: bool, title=None, content=None, media=None):
telegraph = Telegraph() telegraph = Telegraph()
@ -16,7 +17,12 @@ async def post_to_telegraph(is_media: bool, title=None, content=None, media=None
response = await telegraph.upload_file(media) response = await telegraph.upload_file(media)
return f"https://telegra.ph{response[0]['src']}" return f"https://telegra.ph{response[0]['src']}"
"""Create a Telegram Post using HTML Content""" """Create a Telegram Post using HTML Content"""
response = await telegraph.create_page(title, html_content=content, author_url=f"https://t.me/{BOT_USERNAME}", author_name=BOT_USERNAME) response = await telegraph.create_page(
title,
html_content=content,
author_url=f"https://t.me/{BOT_USERNAME}",
author_name=BOT_USERNAME,
)
return response["url"] return response["url"]

View file

@ -146,10 +146,11 @@ padding-top: 0.25rem;
</head> </head>
""" """
from .http import http
import json import json
import re import re
from .http import http
def html_builder(title: str, text: str) -> str: def html_builder(title: str, text: str) -> str:
""" """

View file

@ -6,7 +6,7 @@ import asyncio
import math import math
import time import time
from pyrogram.errors import FloodWait, MessageNotModified, MessageIdInvalid from pyrogram.errors import FloodWait, MessageIdInvalid, MessageNotModified
async def progress_for_pyrogram(current, total, ud_type, message, start, dc_id): async def progress_for_pyrogram(current, total, ud_type, message, start, dc_id):

View file

@ -1,11 +1,11 @@
import logging
import os import os
import random import random
import string import string
import time import time
import logging
from http.cookies import SimpleCookie from http.cookies import SimpleCookie
from urllib.parse import urlparse
from re import match as re_match from re import match as re_match
from urllib.parse import urlparse
import psutil import psutil
@ -15,7 +15,7 @@ from misskaty.helper.human_read import get_readable_time
from misskaty.plugins import ALL_MODULES from misskaty.plugins import ALL_MODULES
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
URL_REGEX = "(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])" URL_REGEX = r"(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])"
GENRES_EMOJI = { GENRES_EMOJI = {
"Action": "👊", "Action": "👊",
"Adventure": random.choice(["🪂", "🧗‍♀", "🌋"]), "Adventure": random.choice(["🪂", "🧗‍♀", "🌋"]),

View file

@ -22,12 +22,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE. SOFTWARE.
""" """
import asyncio import asyncio
import re
import os import os
import re
from logging import getLogger from logging import getLogger
from time import time from time import time
from pyrogram import enums, filters, Client from pyrogram import Client, enums, filters
from pyrogram.errors import ChatAdminRequired, FloodWait from pyrogram.errors import ChatAdminRequired, FloodWait
from pyrogram.types import ChatPermissions, ChatPrivileges, Message from pyrogram.types import ChatPermissions, ChatPrivileges, Message
@ -37,19 +37,19 @@ from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.permissions import ( from misskaty.core.decorator.permissions import (
admins_in_chat, admins_in_chat,
adminsOnly, adminsOnly,
require_admin,
list_admins, list_admins,
member_permissions, member_permissions,
require_admin,
) )
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb from misskaty.core.keyboard import ikb
from misskaty.helper.localization import use_chat_lang
from misskaty.helper.functions import ( from misskaty.helper.functions import (
extract_user, extract_user,
extract_user_and_reason, extract_user_and_reason,
int_to_alpha, int_to_alpha,
time_converter, time_converter,
) )
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, SUDO from misskaty.vars import COMMAND_HANDLER, SUDO
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
@ -174,7 +174,12 @@ async def kickFunc(client: Client, ctx: Message, strings) -> "Message":
if user_id in (await list_admins(ctx.chat.id)): if user_id in (await list_admins(ctx.chat.id)):
return await ctx.reply_msg(strings("kick_admin_err")) return await ctx.reply_msg(strings("kick_admin_err"))
user = await app.get_users(user_id) user = await app.get_users(user_id)
msg = strings("kick_msg").format(mention=user.mention, id=user.id, kicker=ctx.from_user.mention if ctx.from_user else "Anon Admin", reasonmsg=reason or "-") msg = strings("kick_msg").format(
mention=user.mention,
id=user.id,
kicker=ctx.from_user.mention if ctx.from_user else "Anon Admin",
reasonmsg=reason or "-",
)
if ctx.command[0][0] == "d": if ctx.command[0][0] == "d":
await ctx.reply_to_message.delete_msg() await ctx.reply_to_message.delete_msg()
try: try:
@ -210,7 +215,11 @@ async def banFunc(client, message, strings):
except IndexError: except IndexError:
mention = message.reply_to_message.sender_chat.title if message.reply_to_message else "Anon" mention = message.reply_to_message.sender_chat.title if message.reply_to_message else "Anon"
msg = strings("ban_msg").format(mention=mention, id=user_id, banner=message.from_user.mention if message.from_user else "Anon") msg = strings("ban_msg").format(
mention=mention,
id=user_id,
banner=message.from_user.mention if message.from_user else "Anon",
)
if message.command[0][0] == "d": if message.command[0][0] == "d":
await message.reply_to_message.delete() await message.reply_to_message.delete()
if message.command[0] == "tban": if message.command[0] == "tban":
@ -313,7 +322,13 @@ async def list_ban_(c, message, strings):
count += 1 count += 1
mention = (await app.get_users(userid)).mention mention = (await app.get_users(userid)).mention
msg = strings("listban_msg").format(mention=mention, uid=userid, frus=message.from_user.mention, ct=count, reas=reason) msg = strings("listban_msg").format(
mention=mention,
uid=userid,
frus=message.from_user.mention,
ct=count,
reas=reason,
)
await m.edit_text(msg) await m.edit_text(msg)
@ -507,7 +522,10 @@ async def mute(client, message, strings):
return await message.reply_text(strings("mute_admin_err")) return await message.reply_text(strings("mute_admin_err"))
mention = (await app.get_users(user_id)).mention mention = (await app.get_users(user_id)).mention
keyboard = ikb({"🚨 Unmute 🚨": f"unmute_{user_id}"}) keyboard = ikb({"🚨 Unmute 🚨": f"unmute_{user_id}"})
msg = strings("mute_msg").format(mention=mention, muter=message.from_user.mention if message.from_user else "Anon") msg = strings("mute_msg").format(
mention=mention,
muter=message.from_user.mention if message.from_user else "Anon",
)
if message.command[0] == "tmute": if message.command[0] == "tmute":
split = reason.split(None, 1) split = reason.split(None, 1)
time_value = split[0] time_value = split[0]
@ -583,7 +601,12 @@ async def warn_user(client, message, strings):
await remove_warns(chat_id, await int_to_alpha(user_id)) await remove_warns(chat_id, await int_to_alpha(user_id))
else: else:
warn = {"warns": warns + 1} warn = {"warns": warns + 1}
msg = strings("warn_msg").format(mention=mention, warner=message.from_user.mention if message.from_user else "Anon", reas=reason or "No Reason Provided.", twarn=warns + 1) msg = strings("warn_msg").format(
mention=mention,
warner=message.from_user.mention if message.from_user else "Anon",
reas=reason or "No Reason Provided.",
twarn=warns + 1,
)
await message.reply_text(msg, reply_markup=keyboard) await message.reply_text(msg, reply_markup=keyboard)
await add_warn(chat_id, await int_to_alpha(user_id), warn) await add_warn(chat_id, await int_to_alpha(user_id), warn)
@ -743,33 +766,23 @@ async def set_chat_title(self: Client, ctx: Message):
old_title = ctx.chat.title old_title = ctx.chat.title
new_title = ctx.text.split(None, 1)[1] new_title = ctx.text.split(None, 1)[1]
await ctx.chat.set_title(new_title) await ctx.chat.set_title(new_title)
await ctx.reply_text( await ctx.reply_text(f"Successfully Changed Group Title From {old_title} To {new_title}")
f"Successfully Changed Group Title From {old_title} To {new_title}"
)
@app.on_message(filters.command("set_user_title", COMMAND_HANDLER) & ~filters.private) @app.on_message(filters.command("set_user_title", COMMAND_HANDLER) & ~filters.private)
@adminsOnly("can_change_info") @adminsOnly("can_change_info")
async def set_user_title(self: Client, ctx: Message): async def set_user_title(self: Client, ctx: Message):
if not ctx.reply_to_message: if not ctx.reply_to_message:
return await ctx.reply_text( return await ctx.reply_text("Reply to user's message to set his admin title")
"Reply to user's message to set his admin title"
)
if not ctx.reply_to_message.from_user: if not ctx.reply_to_message.from_user:
return await ctx.reply_text( return await ctx.reply_text("I can't change admin title of an unknown entity")
"I can't change admin title of an unknown entity"
)
chat_id = ctx.chat.id chat_id = ctx.chat.id
from_user = ctx.reply_to_message.from_user from_user = ctx.reply_to_message.from_user
if len(ctx.command) < 2: if len(ctx.command) < 2:
return await ctx.reply_text( return await ctx.reply_text("**Usage:**\n/set_user_title NEW ADMINISTRATOR TITLE")
"**Usage:**\n/set_user_title NEW ADMINISTRATOR TITLE"
)
title = ctx.text.split(None, 1)[1] title = ctx.text.split(None, 1)[1]
await app.set_administrator_title(chat_id, from_user.id, title) await app.set_administrator_title(chat_id, from_user.id, title)
await ctx.reply_text( await ctx.reply_text(f"Successfully Changed {from_user.mention}'s Admin Title To {title}")
f"Successfully Changed {from_user.mention}'s Admin Title To {title}"
)
@app.on_message(filters.command("set_chat_photo", COMMAND_HANDLER) & ~filters.private) @app.on_message(filters.command("set_chat_photo", COMMAND_HANDLER) & ~filters.private)
@ -782,14 +795,15 @@ async def set_chat_photo(self: Client, ctx: Message):
file = reply.document or reply.photo file = reply.document or reply.photo
if not file: if not file:
return await ctx.reply_text( return await ctx.reply_text("Reply to a photo or document to set it as chat_photo")
"Reply to a photo or document to set it as chat_photo"
)
if file.file_size > 5000000: if file.file_size > 5000000:
return await ctx.reply("File size too large.") return await ctx.reply("File size too large.")
photo = await reply.download() file = await reply.download()
await ctx.chat.set_photo(photo) try:
await ctx.reply_text("Successfully Changed Group Photo") await ctx.chat.set_photo(photo=photo)
os.remove(photo) await ctx.reply_text("Successfully Changed Group Photo")
except Exception as err:
await ctx.reply(f"Failed changed group photo. ERROR: {err}")
os.remove(photo)

View file

@ -8,11 +8,12 @@
# All rights reserved. # All rights reserved.
# #
# Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import time
import re import re
from pyrogram import filters, enums, Client # Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import time
from pyrogram import Client, enums, filters
from pyrogram.types import Message from pyrogram.types import Message
from database.afk_db import add_afk, cleanmode_off, cleanmode_on, is_afk, remove_afk from database.afk_db import add_afk, cleanmode_off, cleanmode_on, is_afk, remove_afk
@ -54,39 +55,59 @@ async def active_afk(self: Client, ctx: Message, strings):
send = ( send = (
await ctx.reply_animation( await ctx.reply_animation(
data, data,
caption=strings("on_afk_msg_no_r").format(usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago), caption=strings("on_afk_msg_no_r").format(
usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago
),
) )
if str(reasonafk) == "None" if str(reasonafk) == "None"
else await ctx.reply_animation( else await ctx.reply_animation(
data, data,
caption=strings("on_afk_msg_with_r").format(usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago, reas=reasonafk), caption=strings("on_afk_msg_with_r").format(
usr=ctx.from_user.mention,
id=ctx.from_user.id,
tm=seenago,
reas=reasonafk,
),
) )
) )
elif afktype == "photo": elif afktype == "photo":
send = ( send = (
await ctx.reply_photo( await ctx.reply_photo(
photo=f"downloads/{user_id}.jpg", photo=f"downloads/{user_id}.jpg",
caption=strings("on_afk_msg_no_r").format(usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago), caption=strings("on_afk_msg_no_r").format(
usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago
),
) )
if str(reasonafk) == "None" if str(reasonafk) == "None"
else await ctx.reply_photo( else await ctx.reply_photo(
photo=f"downloads/{user_id}.jpg", photo=f"downloads/{user_id}.jpg",
caption=strings("on_afk_msg_with_r").format(usr=ctx.from_user.first_name, tm=seenago, reas=reasonafk), caption=strings("on_afk_msg_with_r").format(
usr=ctx.from_user.first_name, tm=seenago, reas=reasonafk
),
) )
) )
elif afktype == "text": elif afktype == "text":
send = await ctx.reply_text( send = await ctx.reply_text(
strings("on_afk_msg_no_r").format(usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago), strings("on_afk_msg_no_r").format(
usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago
),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
elif afktype == "text_reason": elif afktype == "text_reason":
send = await ctx.reply_text( send = await ctx.reply_text(
strings("on_afk_msg_with_r").format(usr=ctx.from_user.mention, id=ctx.from_user.id, tm=seenago, reas=reasonafk), strings("on_afk_msg_with_r").format(
usr=ctx.from_user.mention,
id=ctx.from_user.id,
tm=seenago,
reas=reasonafk,
),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
except Exception: except Exception:
send = await ctx.reply_text( send = await ctx.reply_text(
strings("is_online").format(usr=ctx.from_user.first_name, id=ctx.from_user.id), strings("is_online").format(
usr=ctx.from_user.first_name, id=ctx.from_user.id
),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
await put_cleanmode(ctx.chat.id, send.id) await put_cleanmode(ctx.chat.id, send.id)
@ -182,7 +203,9 @@ async def active_afk(self: Client, ctx: Message, strings):
} }
await add_afk(user_id, details) await add_afk(user_id, details)
send = await ctx.reply_msg(strings("now_afk").format(usr=ctx.from_user.mention, id=ctx.from_user.id)) send = await ctx.reply_msg(
strings("now_afk").format(usr=ctx.from_user.mention, id=ctx.from_user.id)
)
await put_cleanmode(ctx.chat.id, send.id) await put_cleanmode(ctx.chat.id, send.id)
@ -194,7 +217,9 @@ async def afk_state(self: Client, ctx: Message, strings):
if not ctx.from_user: if not ctx.from_user:
return return
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await ctx.reply_msg(strings("afkdel_help").format(cmd=ctx.command[0]), del_in=6) return await ctx.reply_msg(
strings("afkdel_help").format(cmd=ctx.command[0]), del_in=6
)
chat_id = ctx.chat.id chat_id = ctx.chat.id
state = ctx.text.split(None, 1)[1].strip() state = ctx.text.split(None, 1)[1].strip()
state = state.lower() state = state.lower()
@ -223,9 +248,11 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
possible = ["/afk", f"/afk@{self.me.username}", "!afk"] possible = ["/afk", f"/afk@{self.me.username}", "!afk"]
message_text = ctx.text or ctx.caption message_text = ctx.text or ctx.caption
for entity in ctx.entities: for entity in ctx.entities:
if entity.type == enums.MessageEntityType.BOT_COMMAND: if (
if (message_text[0 : 0 + entity.length]).lower() in possible: entity.type == enums.MessageEntityType.BOT_COMMAND
return and (message_text[0 : 0 + entity.length]).lower() in possible
):
return
msg = "" msg = ""
replied_user_id = 0 replied_user_id = 0
@ -241,30 +268,42 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"] reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk))) seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text": if afktype == "text":
msg += strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago) msg += strings("on_afk_msg_no_r").format(
usr=user_name, id=userid, tm=seenago
)
if afktype == "text_reason": if afktype == "text_reason":
msg += strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk) msg += strings("on_afk_msg_with_r").format(
usr=user_name, id=userid, tm=seenago, reas=reasonafk
)
if afktype == "animation": if afktype == "animation":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago), caption=strings("on_afk_msg_no_r").format(
usr=user_name, id=userid, tm=seenago
),
) )
else: else:
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk), caption=strings("on_afk_msg_with_r").format(
usr=user_name, id=userid, tm=seenago, reas=reasonafk
),
) )
if afktype == "photo": if afktype == "photo":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{userid}.jpg", photo=f"downloads/{userid}.jpg",
caption=strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago), caption=strings("on_afk_msg_no_r").format(
usr=user_name, id=userid, tm=seenago
),
) )
else: else:
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{userid}.jpg", photo=f"downloads/{userid}.jpg",
caption=strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk), caption=strings("on_afk_msg_with_r").format(
usr=user_name, id=userid, tm=seenago, reas=reasonafk
),
) )
except: except:
msg += strings("is_online").format(usr=user_name, id=userid) msg += strings("is_online").format(usr=user_name, id=userid)
@ -283,33 +322,60 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"] reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk))) seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text": if afktype == "text":
msg += strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago) msg += strings("is_afk_msg_no_r").format(
usr=replied_first_name, id=replied_user_id, tm=seenago
)
if afktype == "text_reason": if afktype == "text_reason":
msg += strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk) msg += strings("is_afk_msg_with_r").format(
usr=replied_first_name,
id=replied_user_id,
tm=seenago,
reas=reasonafk,
)
if afktype == "animation": if afktype == "animation":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago), caption=strings("is_afk_msg_no_r").format(
usr=replied_first_name,
id=replied_user_id,
tm=seenago,
),
) )
else: else:
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk), caption=strings("is_afk_msg_with_r").format(
usr=replied_first_name,
id=replied_user_id,
tm=seenago,
reas=reasonafk,
),
) )
if afktype == "photo": if afktype == "photo":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{replied_user_id}.jpg", photo=f"downloads/{replied_user_id}.jpg",
caption=strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago), caption=strings("is_afk_msg_no_r").format(
usr=replied_first_name,
id=replied_user_id,
tm=seenago,
),
) )
else: else:
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{replied_user_id}.jpg", photo=f"downloads/{replied_user_id}.jpg",
caption=strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk), caption=strings("is_afk_msg_with_r").format(
usr=replied_first_name,
id=replied_user_id,
tm=seenago,
reas=reasonafk,
),
) )
except Exception: except Exception:
msg += strings("is_afk").format(usr=replied_first_name, id=replied_user_id) msg += strings("is_afk").format(
usr=replied_first_name, id=replied_user_id
)
except: except:
pass pass
@ -338,33 +404,56 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"] reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk))) seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text": if afktype == "text":
msg += strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago) msg += strings("is_afk_msg_no_r").format(
usr=user.first_name[:25], id=user.id, tm=seenago
)
if afktype == "text_reason": if afktype == "text_reason":
msg += strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk) msg += strings("is_afk_msg_with_r").format(
usr=user.first_name[:25],
id=user.id,
tm=seenago,
reas=reasonafk,
)
if afktype == "animation": if afktype == "animation":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago), caption=strings("is_afk_msg_no_r").format(
usr=user.first_name[:25], id=user.id, tm=seenago
),
) )
else: else:
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk), caption=strings("is_afk_msg_with_r").format(
usr=user.first_name[:25],
id=user.id,
tm=seenago,
reas=reasonafk,
),
) )
if afktype == "photo": if afktype == "photo":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{user.id}.jpg", photo=f"downloads/{user.id}.jpg",
caption=strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago), caption=strings("is_afk_msg_no_r").format(
usr=user.first_name[:25], id=user.id, tm=seenago
),
) )
else: else:
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{user.id}.jpg", photo=f"downloads/{user.id}.jpg",
caption=strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk), caption=strings("is_afk_msg_with_r").format(
usr=user.first_name[:25],
id=user.id,
tm=seenago,
reas=reasonafk,
),
) )
except: except:
msg += strings("is_afk").format(usr=user.first_name[:25], id=user.id) msg += strings("is_afk").format(
usr=user.first_name[:25], id=user.id
)
elif (entity[j].type) == enums.MessageEntityType.TEXT_MENTION: elif (entity[j].type) == enums.MessageEntityType.TEXT_MENTION:
try: try:
user_id = entity[j].user.id user_id = entity[j].user.id
@ -384,30 +473,51 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"] reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk))) seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text": if afktype == "text":
msg += strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago) msg += strings("is_afk_msg_no_r").format(
usr=first_name[:25], id=user_id, tm=seenago
)
if afktype == "text_reason": if afktype == "text_reason":
msg += strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk) msg += strings("is_afk_msg_with_r").format(
usr=first_name[:25],
id=user_id,
tm=seenago,
reas=reasonafk,
)
if afktype == "animation": if afktype == "animation":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago), caption=strings("is_afk_msg_no_r").format(
usr=first_name[:25], id=user_id, tm=seenago
),
) )
else: else:
send = await ctx.reply_animation( send = await ctx.reply_animation(
data, data,
caption=strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk), caption=strings("is_afk_msg_with_r").format(
usr=first_name[:25],
id=user_id,
tm=seenago,
reas=reasonafk,
),
) )
if afktype == "photo": if afktype == "photo":
if str(reasonafk) == "None": if str(reasonafk) == "None":
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{user_id}.jpg", photo=f"downloads/{user_id}.jpg",
caption=strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago), caption=strings("is_afk_msg_no_r").format(
usr=first_name[:25], id=user_id, tm=seenago
),
) )
else: else:
send = await ctx.reply_photo( send = await ctx.reply_photo(
photo=f"downloads/{user_id}.jpg", photo=f"downloads/{user_id}.jpg",
caption=strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk), caption=strings("is_afk_msg_with_r").format(
usr=first_name[:25],
id=user_id,
tm=seenago,
reas=reasonafk,
),
) )
except: except:
msg += strings("is_afk").format(usr=first_name[:25], id=user_id) msg += strings("is_afk").format(usr=first_name[:25], id=user_id)

View file

@ -143,7 +143,10 @@ query ($id: Int, $idMal: Int, $search: String) {
async def get_anime(title): async def get_anime(title):
async with aiohttp.ClientSession() as sesi: async with aiohttp.ClientSession() as sesi:
r = await sesi.post("https://graphql.anilist.co", json={"query": anime_query, "variables": title}) r = await sesi.post(
"https://graphql.anilist.co",
json={"query": anime_query, "variables": title},
)
return await r.read() return await r.read()
@ -168,7 +171,6 @@ async def anime_search(_, mesg):
variables = {"search": search} variables = {"search": search}
if not (res := json.loads(await get_anime(variables))["data"].get("Media", None)): if not (res := json.loads(await get_anime(variables))["data"].get("Media", None)):
return await reply.edit("💢 No Resource Anime found! [404]") return await reply.edit("💢 No Resource Anime found! [404]")
# LOGGER.info(json.dumps(res, indent=3)) # For Debug JSON
durasi = get_readable_time(int(res.get("duration") * 60)) if res.get("duration") is not None else "0" durasi = get_readable_time(int(res.get("duration") * 60)) if res.get("duration") is not None else "0"
msg = f"<b>{res['title']['romaji']}</b> (<code>{res['title']['native']}</code>)\n<b>Type</b>: {res['format']}\n<b>Status</b>: {res['status']}\n<b>Episodes</b>: {res.get('episodes', 'N/A')}\n<b>Duration </b>: {durasi} Per Eps.\n<b>Score</b>: {res['averageScore']}%\n<b>Category</b>: <code>" msg = f"<b>{res['title']['romaji']}</b> (<code>{res['title']['native']}</code>)\n<b>Type</b>: {res['format']}\n<b>Status</b>: {res['status']}\n<b>Episodes</b>: {res.get('episodes', 'N/A')}\n<b>Duration </b>: {durasi} Per Eps.\n<b>Score</b>: {res['averageScore']}%\n<b>Category</b>: <code>"
for x in res["genres"]: for x in res["genres"]:

View file

@ -1,7 +1,6 @@
""" """
* @author yasir <yasiramunandar@gmail.com> * @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27 * @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
@ -10,8 +9,8 @@ from pyrogram.errors import UserAlreadyParticipant, UserIsBlocked
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
# Filters Approve User by bot in channel @YMovieZNew # Filters Approve User by bot in channel @YMovieZNew

View file

@ -20,7 +20,9 @@ LOGGER = getLogger(__name__)
async def FilterMessage(message: Message): async def FilterMessage(message: Message):
if (message.forward_from or message.forward_from_chat) and ("forwarded" not in FORWARD_FILTERS): if (message.forward_from or message.forward_from_chat) and (
"forwarded" not in FORWARD_FILTERS
):
return 400 return 400
if (len(FORWARD_FILTERS) == 9) or ( if (len(FORWARD_FILTERS) == 9) or (
(message.video and ("video" in FORWARD_FILTERS)) (message.video and ("video" in FORWARD_FILTERS))
@ -44,7 +46,10 @@ async def CheckBlockedExt(event: Message):
if (media is not None) and (media.file_name is not None): if (media is not None) and (media.file_name is not None):
_file = media.file_name.rsplit(".", 1) _file = media.file_name.rsplit(".", 1)
if len(_file) == 2: if len(_file) == 2:
return _file[-1].lower() in BLOCKED_EXTENSIONS or _file[-1].upper() in BLOCKED_EXTENSIONS return (
_file[-1].lower() in BLOCKED_EXTENSIONS
or _file[-1].upper() in BLOCKED_EXTENSIONS
)
else: else:
return False return False
@ -70,15 +75,17 @@ async def ForwardMessage(client: user, msg: Message):
if file_size_passed is False: if file_size_passed is False:
return 400 return 400
## --- Check 4 --- ## ## --- Check 4 --- ##
for i in range(len(FORWARD_TO_CHAT_ID)): for item in FORWARD_TO_CHAT_ID:
try: try:
await msg.copy(FORWARD_TO_CHAT_ID[i]) await msg.copy(item)
except FloodWait as e: except FloodWait as e:
await sleep(e.value) await sleep(e.value)
LOGGER.warning(f"#FloodWait: Stopped Forwarder for {e.x}s!") LOGGER.warning(f"#FloodWait: Stopped Forwarder for {e.x}s!")
await ForwardMessage(client, msg) await ForwardMessage(client, msg)
except Exception as err: except Exception as err:
LOGGER.warning(f"#ERROR: {err}\n\nUnable to Forward Message to {str(FORWARD_TO_CHAT_ID[i])}, reason: <code>{err}</code>") LOGGER.warning(
f"#ERROR: {err}\n\nUnable to Forward Message to {str(item)}, reason: <code>{err}</code>"
)
except: except:
pass pass

View file

@ -1,10 +1,11 @@
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.errors import ChannelPrivate
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from database.users_chats_db import db from database.users_chats_db import db
from misskaty import app from misskaty import app
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.vars import SUPPORT_CHAT, SUDO, LOG_CHANNEL, COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO, SUPPORT_CHAT
@app.on_message(filters.incoming, group=-1) @app.on_message(filters.incoming, group=-1)
@ -12,8 +13,12 @@ async def ban_reply(self: Client, ctx: Message):
if not ctx.from_user: if not ctx.from_user:
return return
ban = await db.get_ban_status(ctx.from_user.id) ban = await db.get_ban_status(ctx.from_user.id)
if (ban.get("is_banned") and ctx.chat.type.value == "private") or (ban.get("is_banned") and ctx.chat.type.value == "supergroup" and ctx.command): if (ban.get("is_banned") and ctx.chat.type.value == "private") or (
await ctx.reply_msg(f'I am sorry, You are banned to use Me. \nBan Reason: {ban["ban_reason"]}') ban.get("is_banned") and ctx.chat.type.value == "supergroup" and ctx.command
):
await ctx.reply_msg(
f'I am sorry, You are banned to use Me. \nBan Reason: {ban["ban_reason"]}'
)
await ctx.stop_propagation() await ctx.stop_propagation()
@ -23,16 +28,23 @@ async def grp_bd(self: Client, ctx: Message, strings):
if not ctx.from_user: if not ctx.from_user:
return return
if not await db.is_chat_exist(ctx.chat.id): if not await db.is_chat_exist(ctx.chat.id):
total = await self.get_chat_members_count(ctx.chat.id) try:
total = await self.get_chat_members_count(ctx.chat.id)
except ChannelPrivate:
await ctx.stop_propagation()
r_j = ctx.from_user.mention if ctx.from_user else "Anonymous" r_j = ctx.from_user.mention if ctx.from_user else "Anonymous"
await self.send_message( await self.send_message(
LOG_CHANNEL, LOG_CHANNEL,
strings("log_bot_added", context="grup_tools").format(ttl=ctx.chat.title, cid=ctx.chat.id, tot=total, r_j=r_j), strings("log_bot_added", context="grup_tools").format(
ttl=ctx.chat.title, cid=ctx.chat.id, tot=total, r_j=r_j
),
) )
await db.add_chat(ctx.chat.id, ctx.chat.title) await db.add_chat(ctx.chat.id, ctx.chat.title)
chck = await db.get_chat(ctx.chat.id) chck = await db.get_chat(ctx.chat.id)
if chck['is_disabled']: if chck["is_disabled"]:
buttons = [[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]] buttons = [
[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]
]
reply_markup = InlineKeyboardMarkup(buttons) reply_markup = InlineKeyboardMarkup(buttons)
vazha = await db.get_chat(ctx.chat.id) vazha = await db.get_chat(ctx.chat.id)
try: try:
@ -50,7 +62,7 @@ async def grp_bd(self: Client, ctx: Message, strings):
@app.on_message(filters.command("banuser", COMMAND_HANDLER) & filters.user(SUDO)) @app.on_message(filters.command("banuser", COMMAND_HANDLER) & filters.user(SUDO))
async def ban_a_user(bot, message): async def ban_a_user(bot, message):
if len(message.command) == 1: if len(message.command) == 1:
return await message.reply('Give me a user id / username') return await message.reply("Give me a user id / username")
r = message.text.split(None) r = message.text.split(None)
if len(r) > 2: if len(r) > 2:
reason = message.text.split(None, 2)[2] reason = message.text.split(None, 2)[2]
@ -65,31 +77,29 @@ async def ban_a_user(bot, message):
try: try:
k = await bot.get_users(chat) k = await bot.get_users(chat)
except PeerIdInvalid: except PeerIdInvalid:
return await message.reply("This is an invalid user, make sure i have met him before.") return await message.reply(
"This is an invalid user, make sure i have met him before."
)
except IndexError: except IndexError:
return await message.reply("This might be a channel, make sure its a user.") return await message.reply("This might be a channel, make sure its a user.")
except Exception as e: except Exception as e:
return await message.reply(f'Error - {e}') return await message.reply(f"Error - {e}")
else: else:
jar = await db.get_ban_status(k.id) jar = await db.get_ban_status(k.id)
if jar['is_banned']: if jar["is_banned"]:
return await message.reply(f"{k.mention} is already banned\nReason: {jar['ban_reason']}") return await message.reply(
f"{k.mention} is already banned\nReason: {jar['ban_reason']}"
)
await db.ban_user(k.id, reason) await db.ban_user(k.id, reason)
await message.reply(f"Successfully banned user {k.mention}!! Reason: {reason}") await message.reply(f"Successfully banned user {k.mention}!! Reason: {reason}")
@app.on_message(filters.command("unbanuser", COMMAND_HANDLER) & filters.user(SUDO)) @app.on_message(filters.command("unbanuser", COMMAND_HANDLER) & filters.user(SUDO))
async def unban_a_user(bot, message): async def unban_a_user(bot, message):
if len(message.command) == 1: if len(message.command) == 1:
return await message.reply('Give me a user id / username') return await message.reply("Give me a user id / username")
r = message.text.split(None) r = message.text.split(None)
if len(r) > 2: chat = message.text.split(None, 2)[1] if len(r) > 2 else message.command[1]
reason = message.text.split(None, 2)[2]
chat = message.text.split(None, 2)[1]
else:
chat = message.command[1]
reason = "No reason Provided"
try: try:
chat = int(chat) chat = int(chat)
except: except:
@ -97,14 +107,16 @@ async def unban_a_user(bot, message):
try: try:
k = await bot.get_users(chat) k = await bot.get_users(chat)
except PeerIdInvalid: except PeerIdInvalid:
return await message.reply("This is an invalid user, make sure ia have met him before.") return await message.reply(
"This is an invalid user, make sure ia have met him before."
)
except IndexError: except IndexError:
return await message.reply("This might be a channel, make sure its a user.") return await message.reply("This might be a channel, make sure its a user.")
except Exception as e: except Exception as e:
return await message.reply(f'Error - {e}') return await message.reply(f"Error - {e}")
else: else:
jar = await db.get_ban_status(k.id) jar = await db.get_ban_status(k.id)
if not jar['is_banned']: if not jar["is_banned"]:
return await message.reply(f"{k.mention} is not yet banned.") return await message.reply(f"{k.mention} is not yet banned.")
await db.remove_ban(k.id) await db.remove_ban(k.id)
await message.reply(f"Successfully unbanned user {k.mention}!!!") await message.reply(f"Successfully unbanned user {k.mention}!!!")
@ -129,11 +141,15 @@ async def disable_chat(bot, message):
if not cha_t: if not cha_t:
return await message.reply("Chat Not Found In DB") return await message.reply("Chat Not Found In DB")
if cha_t["is_disabled"]: if cha_t["is_disabled"]:
return await message.reply(f"This chat is already disabled:\nReason-<code> {cha_t['reason']} </code>") return await message.reply(
f"This chat is already disabled:\nReason-<code> {cha_t['reason']} </code>"
)
await db.disable_chat(chat_, reason) await db.disable_chat(chat_, reason)
await message.reply("Chat Succesfully Disabled") await message.reply("Chat Succesfully Disabled")
try: try:
buttons = [[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]] buttons = [
[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]
]
reply_markup = InlineKeyboardMarkup(buttons) reply_markup = InlineKeyboardMarkup(buttons)
await bot.send_message( await bot.send_message(
chat_id=chat_, chat_id=chat_,
@ -160,4 +176,4 @@ async def re_enable_chat(bot: Client, ctx: Message):
if not sts.get("is_disabled"): if not sts.get("is_disabled"):
return await ctx.reply("This chat is not yet disabled.") return await ctx.reply("This chat is not yet disabled.")
await db.re_enable_chat(chat_) await db.re_enable_chat(chat_)
await ctx.reply("Chat Succesfully re-enabled") await ctx.reply("Chat Succesfully re-enabled")

View file

@ -2,7 +2,7 @@ import asyncio
import datetime import datetime
import time import time
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message from pyrogram.types import Message
from database.users_chats_db import db from database.users_chats_db import db

View file

@ -10,14 +10,14 @@ import urllib.parse
from urllib.parse import unquote from urllib.parse import unquote
import requests import requests
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.errors import EntitiesTooLong, MessageTooLong from pyrogram.errors import EntitiesTooLong, MessageTooLong
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from misskaty import app from misskaty import app
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import http, get_readable_file_size, rentry from misskaty.helper import get_readable_file_size, http, rentry
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
LIST_LINK = """ LIST_LINK = """
@ -94,7 +94,6 @@ async def bypass(self: Client, ctx: Message):
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await ctx.reply_msg(f"Gunakan perintah /{ctx.command[0]} untuk bypass url", del_in=6) return await ctx.reply_msg(f"Gunakan perintah /{ctx.command[0]} untuk bypass url", del_in=6)
url = ctx.command[1] url = ctx.command[1]
urllib.parse.urlparse(url).netloc
msg = await ctx.reply_msg("Bypassing URL..", quote=True) msg = await ctx.reply_msg("Bypassing URL..", quote=True)
mention = f"**Bypasser:** {ctx.from_user.mention} ({ctx.from_user.id})" mention = f"**Bypasser:** {ctx.from_user.mention} ({ctx.from_user.id})"
if re.match(r"https?://(store.kde.org|www.pling.com)\/p\/(\d+)", url): if re.match(r"https?://(store.kde.org|www.pling.com)\/p\/(\d+)", url):

View file

@ -1,20 +1,26 @@
import openai # * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import asyncio import asyncio
import html import html
import openai
from aiohttp import ClientSession from aiohttp import ClientSession
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message
from pyrogram.errors import MessageTooLong from pyrogram.errors import MessageTooLong
from pyrogram.types import Message
from misskaty import app from misskaty import app
from misskaty.helper.localization import use_chat_lang
from misskaty.helper import post_to_telegraph, check_time_gap
from misskaty.helper.http import http
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import check_time_gap, post_to_telegraph
from misskaty.helper.http import http
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, OPENAI_API, SUDO from misskaty.vars import COMMAND_HANDLER, OPENAI_API, SUDO
openai.api_key = OPENAI_API openai.api_key = OPENAI_API
# This only for testing things, since maybe in future it will got blocked # This only for testing things, since maybe in future it will got blocked
@app.on_message(filters.command("bard", COMMAND_HANDLER)) @app.on_message(filters.command("bard", COMMAND_HANDLER))
@use_chat_lang() @use_chat_lang()
@ -22,13 +28,17 @@ async def bard_chatbot(self: Client, ctx: Message, strings):
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await ctx.reply_msg(strings("no_question").format(cmd=ctx.command[0]), quote=True, del_in=5) return await ctx.reply_msg(strings("no_question").format(cmd=ctx.command[0]), quote=True, del_in=5)
msg = await ctx.reply_msg(strings("find_answers_str"), quote=True) msg = await ctx.reply_msg(strings("find_answers_str"), quote=True)
data = {'message': ctx.input, 'session_id':'XQjzKRYITZ7fhplF-rXa_GTynUwdctKq4aGm-lqUCCJzF98xqDulL9UKopIadNpQn0lvnA.'} data = {
"message": ctx.input,
"session_id": "XQjzKRYITZ7fhplF-rXa_GTynUwdctKq4aGm-lqUCCJzF98xqDulL9UKopIadNpQn0lvnA.",
}
try: try:
req = await http.post("https://bard-api-rho.vercel.app/ask", json=data) req = await http.post("https://bard-api-rho.vercel.app/ask", json=data)
await msg.edit_msg(req.json().get("content")) await msg.edit_msg(req.json().get("content"))
except Exception as e: except Exception as e:
await msg.edit_msg(str(e)) await msg.edit_msg(str(e))
@app.on_message(filters.command("ask", COMMAND_HANDLER)) @app.on_message(filters.command("ask", COMMAND_HANDLER))
@ratelimiter @ratelimiter
@use_chat_lang() @use_chat_lang()
@ -45,7 +55,12 @@ async def openai_chatbot(self: Client, ctx: Message, strings):
num = 0 num = 0
answer = "" answer = ""
try: try:
response = await openai.ChatCompletion.acreate(model="gpt-3.5-turbo", messages=[{"role": "user", "content": pertanyaan}], temperature=0.7, stream=True) response = await openai.ChatCompletion.acreate(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": pertanyaan}],
temperature=0.7,
stream=True,
)
async for chunk in response: async for chunk in response:
if not chunk.choices[0].delta or chunk.choices[0].delta.get("role"): if not chunk.choices[0].delta or chunk.choices[0].delta.get("role"):
continue continue
@ -58,7 +73,10 @@ async def openai_chatbot(self: Client, ctx: Message, strings):
await msg.edit_msg(answer) await msg.edit_msg(answer)
except MessageTooLong: except MessageTooLong:
answerlink = await post_to_telegraph(False, "MissKaty ChatBot ", html.escape(answer)) answerlink = await post_to_telegraph(False, "MissKaty ChatBot ", html.escape(answer))
await msg.edit_msg(strings("answers_too_long").format(answerlink=answerlink), disable_web_page_preview=True) await msg.edit_msg(
strings("answers_too_long").format(answerlink=answerlink),
disable_web_page_preview=True,
)
except Exception as err: except Exception as err:
await msg.edit_msg(f"ERROR: {str(err)}") await msg.edit_msg(f"ERROR: {str(err)}")
await openai.aiosession.get().close() await openai.aiosession.get().close()

View file

@ -3,8 +3,8 @@ from pyrogram import enums, filters
from pyrogram.errors import MessageTooLong from pyrogram.errors import MessageTooLong
from misskaty import app from misskaty import app
from misskaty.helper.tools import rentry
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.tools import rentry
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "CodeTester" __MODULE__ = "CodeTester"

View file

@ -3,8 +3,8 @@ from pyrogram.errors import UserIsBlocked, UserNotParticipant
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import BOT_USERNAME, app from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER

View file

@ -1,11 +1,16 @@
from pyrogram import filters, Client # * @author Yasir Aris M <yasiramunandar@gmail.com>
from pyrogram.types import Message # * @date 2023-06-21 22:12:27
from misskaty import app # * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import logging import logging
from pyrogram import Client, filters
from pyrogram.types import Message
from misskaty import app
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER, CURRENCY_API from misskaty.vars import COMMAND_HANDLER, CURRENCY_API
__MODULE__ = "Currency" __MODULE__ = "Currency"
__HELP__ = """ __HELP__ = """
/currency - Send structure message Telegram in JSON using Pyrogram Style. /currency - Send structure message Telegram in JSON using Pyrogram Style.
@ -22,13 +27,16 @@ async def currency(self: Client, ctx: Message):
disable_web_page_preview=True, disable_web_page_preview=True,
) )
if len(ctx.text.split()) != 4: if len(ctx.text.split()) != 4:
return await ctx.reply_msg(f"Use format /{ctx.command[0]} [amount] [currency_from] [currency_to] to convert currency.", del_in=6) return await ctx.reply_msg(
f"Use format /{ctx.command[0]} [amount] [currency_from] [currency_to] to convert currency.",
del_in=6,
)
teks = ctx.text.split() teks = ctx.text.split()
amount = teks[1] amount = teks[1]
currency_from = teks[2] currency_from = teks[2]
currency_to = teks[3] currency_to = teks[3]
if amount.isdigit() or (amount.replace('.','',1).isdigit() and amount.count('.') < 2): if amount.isdigit() or (amount.replace(".", "", 1).isdigit() and amount.count(".") < 2):
url = f"https://v6.exchangerate-api.com/v6/{CURRENCY_API}/" f"pair/{currency_from}/{currency_to}/{amount}" url = f"https://v6.exchangerate-api.com/v6/{CURRENCY_API}/" f"pair/{currency_from}/{currency_to}/{amount}"
try: try:
res = await http.get(url) res = await http.get(url)
@ -41,7 +49,9 @@ async def currency(self: Client, ctx: Message):
last_update = data["time_last_update_utc"] last_update = data["time_last_update_utc"]
except KeyError: except KeyError:
return await ctx.reply_msg("<code>Invalid response from api !</i>") return await ctx.reply_msg("<code>Invalid response from api !</i>")
await ctx.reply_msg(f"**CURRENCY EXCHANGE RATE RESULT:**\n\n`{format(float(amount), ',')}` **{base_code}** = `{format(float(conversion_result), ',')}` **{target_code}**\n<b>Rate Today</b> = `{format(float(conversion_rate), ',')}`\n<b>Last Update:</b> {last_update}") await ctx.reply_msg(
f"**CURRENCY EXCHANGE RATE RESULT:**\n\n`{format(float(amount), ',')}` **{base_code}** = `{format(float(conversion_result), ',')}` **{target_code}**\n<b>Rate Today</b> = `{format(float(conversion_rate), ',')}`\n<b>Last Update:</b> {last_update}"
)
except Exception as err: except Exception as err:
await ctx.reply_msg(f"Failed convert currency, maybe you give wrong currency format or api down.\n\n<b>ERROR</b>: {err}") await ctx.reply_msg(f"Failed convert currency, maybe you give wrong currency format or api down.\n\n<b>ERROR</b>: {err}")
else: else:

View file

@ -1,44 +1,47 @@
import asyncio import asyncio
import contextlib
import html
import io import io
import json
import os import os
import pickle
import re import re
import sys import sys
import html
import pickle
import json
import traceback import traceback
import cloudscraper
import aiohttp
import logging
from datetime import datetime from datetime import datetime
from inspect import getfullargspec
from shutil import disk_usage from shutil import disk_usage
from time import time from time import time
from database.users_chats_db import db
from inspect import getfullargspec
from typing import Any, Optional, Tuple from typing import Any, Optional, Tuple
from database.gban_db import is_gbanned_user, add_gban_user, remove_gban_user
from psutil import cpu_percent, Process import aiohttp
from psutil import disk_usage as disk_usage_percent import cloudscraper
from psutil import virtual_memory, cpu_count, boot_time, net_io_counters
from pyrogram import enums, filters, Client, __version__ as pyrover
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message, InputMediaPhoto
from pyrogram.raw.types import UpdateBotStopped
from pyrogram.errors import PeerIdInvalid, FloodWait
from pykeyboard import InlineKeyboard, InlineButton
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from psutil import Process, boot_time, cpu_count, cpu_percent
from misskaty import app, user, botStartTime, misskaty_version, BOT_NAME from psutil import disk_usage as disk_usage_percent
from misskaty.helper.http import http from psutil import net_io_counters, virtual_memory
from misskaty.helper.eval_helper import meval, format_exception from pykeyboard import InlineButton, InlineKeyboard
from misskaty.helper.localization import use_chat_lang from pyrogram import Client
from misskaty.helper.functions import ( from pyrogram import __version__ as pyrover
extract_user, from pyrogram import enums, filters
extract_user_and_reason from pyrogram.errors import FloodWait, PeerIdInvalid
from pyrogram.raw.types import UpdateBotStopped
from pyrogram.types import (
InlineKeyboardButton,
InlineKeyboardMarkup,
InputMediaPhoto,
Message,
) )
from database.gban_db import add_gban_user, is_gbanned_user, remove_gban_user
from database.users_chats_db import db
from misskaty import BOT_NAME, app, botStartTime, misskaty_version, user
from misskaty.helper.eval_helper import format_exception, meval
from misskaty.helper.functions import extract_user, extract_user_and_reason
from misskaty.helper.http import http
from misskaty.helper.human_read import get_readable_file_size, get_readable_time from misskaty.helper.human_read import get_readable_file_size, get_readable_time
from misskaty.vars import COMMAND_HANDLER, SUDO, LOG_CHANNEL from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO
__MODULE__ = "DevCommand" __MODULE__ = "DevCommand"
__HELP__ = """ __HELP__ = """
@ -102,19 +105,25 @@ async def log_file(self: Client, ctx: Message, strings) -> "Message":
async def donate(client, ctx): async def donate(client, ctx):
keyboard = InlineKeyboard(row_width=2) keyboard = InlineKeyboard(row_width=2)
keyboard.add( keyboard.add(
InlineButton('QR QRIS [Yasir Store]', url='https://telegra.ph/file/2acf7698f300ef3d9138f.jpg'), InlineButton(
InlineButton('Sociabuzz', url='https://sociabuzz.com/yasirarism/tribe'), "QR QRIS [Yasir Store]",
InlineButton('Saweria', url='https://saweria.co/yasirarism'), url="https://telegra.ph/file/2acf7698f300ef3d9138f.jpg",
InlineButton('Trakteer', url='https://trakteer.id/yasir-aris-sp7cn'), ),
InlineButton('Ko-Fi', url='https://ko-fi.com/yasirarism'), InlineButton("Sociabuzz", url="https://sociabuzz.com/yasirarism/tribe"),
InlineButton('PayPal', url='https://paypal.me/yasirarism'), InlineButton("Saweria", url="https://saweria.co/yasirarism"),
InlineButton("Trakteer", url="https://trakteer.id/yasir-aris-sp7cn"),
InlineButton("Ko-Fi", url="https://ko-fi.com/yasirarism"),
InlineButton("PayPal", url="https://paypal.me/yasirarism"),
) )
await ctx.reply( await ctx.reply(
f"Hai {ctx.from_user.mention}, jika kamu merasa bot ini besrguna bisa melakukan donasi dengan ke rekening diatas yaa (disarankan menggunakan QRIS atau Sociabuzz). Karena server bot ini menggunakan VPS dan tidaklah gratis. Terimakasih..\n\nHi {ctx.from_user.mention}, if you feel this bot is useful, you can make a donation to the account above (Use PayPal, SociaBuzz, or Ko-Fi). Because this bot server is hosted in VPS and not free. Thank you..", reply_markup=keyboard f"Hai {ctx.from_user.mention}, jika kamu merasa bot ini besrguna bisa melakukan donasi dengan ke rekening diatas yaa (disarankan menggunakan QRIS atau Sociabuzz). Karena server bot ini menggunakan VPS dan tidaklah gratis. Terimakasih..\n\nHi {ctx.from_user.mention}, if you feel this bot is useful, you can make a donation to the account above (Use PayPal, SociaBuzz, or Ko-Fi). Because this bot server is hosted in VPS and not free. Thank you..",
reply_markup=keyboard,
) )
@app.on_message(filters.command(["balas"], COMMAND_HANDLER) & filters.user(SUDO) & filters.reply) @app.on_message(
filters.command(["balas"], COMMAND_HANDLER) & filters.user(SUDO) & filters.reply
)
async def balas(self: Client, ctx: Message) -> "str": async def balas(self: Client, ctx: Message) -> "str":
pesan = ctx.input pesan = ctx.input
await ctx.delete_msg() await ctx.delete_msg()
@ -244,14 +253,11 @@ async def ban_globally(self: Client, ctx: Message):
await asyncio.sleep(int(e.value)) await asyncio.sleep(int(e.value))
except Exception: except Exception:
pass pass
try: with contextlib.suppress(Exception):
await app.send_message( await app.send_message(
user_id, user_id,
f"Hello, You have been globally banned by {from_user.mention}," f"Hello, You have been globally banned by {from_user.mention}, You can appeal for this ban by talking to him.",
+ " You can appeal for this ban by talking to him.",
) )
except Exception:
pass
await m.edit(f"Banned {user_mention} Globally!") await m.edit(f"Banned {user_mention} Globally!")
ban_text = f""" ban_text = f"""
__**New Global Ban**__ __**New Global Ban**__
@ -299,14 +305,22 @@ async def unban_globally(self: Client, ctx: Message):
await ctx.reply_text(f"Lifted {user_mention}'s Global Ban.'") await ctx.reply_text(f"Lifted {user_mention}'s Global Ban.'")
@app.on_message(filters.command(["shell", "sh", "term"], COMMAND_HANDLER) & filters.user(SUDO)) @app.on_message(
@app.on_edited_message(filters.command(["shell", "sh", "term"], COMMAND_HANDLER) & filters.user(SUDO)) filters.command(["shell", "sh", "term"], COMMAND_HANDLER) & filters.user(SUDO)
)
@app.on_edited_message(
filters.command(["shell", "sh", "term"], COMMAND_HANDLER) & filters.user(SUDO)
)
@user.on_message(filters.command(["shell", "sh", "term"], ".") & filters.me) @user.on_message(filters.command(["shell", "sh", "term"], ".") & filters.me)
@use_chat_lang() @use_chat_lang()
async def shell(self: Client, ctx: Message, strings) -> "Message": async def shell(self: Client, ctx: Message, strings) -> "Message":
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await edit_or_reply(ctx, text=strings("no_cmd")) return await edit_or_reply(ctx, text=strings("no_cmd"))
msg = await ctx.edit_msg(strings("run_exec")) if ctx.from_user.is_self else await ctx.reply_msg(strings("run_exec")) msg = (
await ctx.edit_msg(strings("run_exec"))
if ctx.from_user.is_self
else await ctx.reply_msg(strings("run_exec"))
)
shell = (await shell_exec(ctx.input))[0] shell = (await shell_exec(ctx.input))[0]
if len(shell) > 3000: if len(shell) > 3000:
with io.BytesIO(str.encode(shell)) as doc: with io.BytesIO(str.encode(shell)) as doc:
@ -332,7 +346,16 @@ async def shell(self: Client, ctx: Message, strings) -> "Message":
ctx, ctx,
text=html.escape(shell), text=html.escape(shell),
parse_mode=enums.ParseMode.HTML, parse_mode=enums.ParseMode.HTML,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{ctx.from_user.id}")]]), reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text=strings("cl_btn"),
callback_data=f"close#{ctx.from_user.id}",
)
]
]
),
) )
if not ctx.from_user.is_self: if not ctx.from_user.is_self:
await msg.delete_msg() await msg.delete_msg()
@ -340,15 +363,30 @@ async def shell(self: Client, ctx: Message, strings) -> "Message":
await ctx.reply_msg(strings("no_reply"), del_in=5) await ctx.reply_msg(strings("no_reply"), del_in=5)
@app.on_message((filters.command(["ev", "run", "myeval"], COMMAND_HANDLER) | filters.regex(r"app.run\(\)$")) & filters.user(SUDO)) @app.on_message(
@app.on_edited_message((filters.command(["ev", "run", "myeval"]) | filters.regex(r"app.run\(\)$")) & filters.user(SUDO)) (
filters.command(["ev", "run", "myeval"], COMMAND_HANDLER)
| filters.regex(r"app.run\(\)$")
)
& filters.user(SUDO)
)
@app.on_edited_message(
(filters.command(["ev", "run", "myeval"]) | filters.regex(r"app.run\(\)$"))
& filters.user(SUDO)
)
@user.on_message(filters.command(["ev", "run", "myeval"], ".") & filters.me) @user.on_message(filters.command(["ev", "run", "myeval"], ".") & filters.me)
@use_chat_lang() @use_chat_lang()
async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]: async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
if (ctx.command and len(ctx.command) == 1) or ctx.text == "app.run()": if (ctx.command and len(ctx.command) == 1) or ctx.text == "app.run()":
return await edit_or_reply(ctx, text=strings("no_eval")) return await edit_or_reply(ctx, text=strings("no_eval"))
status_message = await ctx.edit_msg(strings("run_eval")) if ctx.from_user.is_self else await ctx.reply_msg(strings("run_eval"), quote=True) status_message = (
code = ctx.text.split(" ", 1)[1] if ctx.command else ctx.text.split("\napp.run()")[0] await ctx.edit_msg(strings("run_eval"))
if ctx.from_user.is_self
else await ctx.reply_msg(strings("run_eval"), quote=True)
)
code = (
ctx.text.split(" ", 1)[1] if ctx.command else ctx.text.split("\napp.run()")[0]
)
out_buf = io.StringIO() out_buf = io.StringIO()
out = "" out = ""
humantime = get_readable_time humantime = get_readable_time
@ -365,6 +403,10 @@ async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
kwargs["file"] = out_buf kwargs["file"] = out_buf
return print(*args, **kwargs) return print(*args, **kwargs)
def _help(*args: Any, **kwargs: Any) -> None:
with contextlib.redirect_stdout(out_buf):
help(*args, **kwargs)
eval_vars = { eval_vars = {
"self": self, "self": self,
"humantime": humantime, "humantime": humantime,
@ -383,6 +425,7 @@ async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
"traceback": traceback, "traceback": traceback,
"http": http, "http": http,
"replied": ctx.reply_to_message, "replied": ctx.reply_to_message,
"help": _help,
} }
eval_vars.update(var) eval_vars.update(var)
eval_vars.update(teskode) eval_vars.update(teskode)
@ -446,7 +489,16 @@ async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
ctx, ctx,
text=final_output, text=final_output,
parse_mode=enums.ParseMode.HTML, parse_mode=enums.ParseMode.HTML,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{ctx.from_user.id}")]]), reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text=strings("cl_btn"),
callback_data=f"close#{ctx.from_user.id}",
)
]
]
),
) )
if not ctx.from_user.is_self: if not ctx.from_user.is_self:
await status_message.delete_msg() await status_message.delete_msg()
@ -468,22 +520,35 @@ async def update_restart(self: Client, ctx: Message, strings) -> "Message":
pickle.dump([ctx.chat.id, msg.id], status) pickle.dump([ctx.chat.id, msg.id], status)
os.execvp(sys.executable, [sys.executable, "-m", "misskaty"]) os.execvp(sys.executable, [sys.executable, "-m", "misskaty"])
@app.on_raw_update(group=-99) @app.on_raw_update(group=-99)
async def updtebot(client, update, users, chats): async def updtebot(client, update, users, chats):
if isinstance(update, UpdateBotStopped): if isinstance(update, UpdateBotStopped):
user = users[update.user_id] user = users[update.user_id]
if update.stopped and await db.is_user_exist(user.id): if update.stopped and await db.is_user_exist(user.id):
await db.delete_user(user.id) await db.delete_user(user.id)
await client.send_msg(LOG_CHANNEL, f"<a href='tg://user?id={user.id}'>{user.first_name}</a> (<code>{user.id}</code>) " f"{'BLOCKED' if update.stopped else 'UNBLOCKED'} the bot at " f"{datetime.fromtimestamp(update.date)}") await client.send_msg(
LOG_CHANNEL,
f"<a href='tg://user?id={user.id}'>{user.first_name}</a> (<code>{user.id}</code>) "
f"{'BLOCKED' if update.stopped else 'UNBLOCKED'} the bot at "
f"{datetime.fromtimestamp(update.date)}",
)
async def aexec(code, c, m): async def aexec(code, c, m):
exec("async def __aexec(c, m): " + "\n p = print" + "\n replied = m.reply_to_message" + "".join(f"\n {l_}" for l_ in code.split("\n"))) exec(
"async def __aexec(c, m): "
+ "\n p = print"
+ "\n replied = m.reply_to_message"
+ "".join(f"\n {l_}" for l_ in code.split("\n"))
)
return await locals()["__aexec"](c, m) return await locals()["__aexec"](c, m)
async def shell_exec(code, treat=True): async def shell_exec(code, treat=True):
process = await asyncio.create_subprocess_shell(code, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT) process = await asyncio.create_subprocess_shell(
code, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.STDOUT
)
stdout = (await process.communicate())[0] stdout = (await process.communicate())[0]
if treat: if treat:

View file

@ -1,3 +1,7 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import asyncio import asyncio
import math import math
import os import os
@ -37,7 +41,12 @@ __HELP__ = """
async def upload(bot, message): async def upload(bot, message):
if not message.reply_to_message: if not message.reply_to_message:
return await message.reply("Please reply to media file.") return await message.reply("Please reply to media file.")
vid = [message.reply_to_message.video, message.reply_to_message.document, message.reply_to_message.audio, message.reply_to_message.photo] vid = [
message.reply_to_message.video,
message.reply_to_message.document,
message.reply_to_message.audio,
message.reply_to_message.photo,
]
media = next((v for v in vid if v is not None), None) media = next((v for v in vid if v is not None), None)
if not media: if not media:
return await message.reply("Unsupported media type..") return await message.reply("Unsupported media type..")
@ -70,7 +79,12 @@ async def download(client, message):
if message.reply_to_message is not None: if message.reply_to_message is not None:
start_t = datetime.now() start_t = datetime.now()
c_time = time.time() c_time = time.time()
vid = [message.reply_to_message.video, message.reply_to_message.document, message.reply_to_message.audio, message.reply_to_message.photo] vid = [
message.reply_to_message.video,
message.reply_to_message.document,
message.reply_to_message.audio,
message.reply_to_message.photo,
]
media = next((v for v in vid if v is not None), None) media = next((v for v in vid if v is not None), None)
if not media: if not media:
return await pesan.edit_msg("Unsupported media type..") return await pesan.edit_msg("Unsupported media type..")
@ -172,7 +186,11 @@ async def fbdl(client, message):
obj = SmartDL(url, progress_bar=False, timeout=10) obj = SmartDL(url, progress_bar=False, timeout=10)
obj.start() obj.start()
path = obj.get_dest() path = obj.get_dest()
await message.reply_video(path, caption=f"<code>{os.path.basename(path)}</code>\n\nUploaded for {message.from_user.mention} [<code>{message.from_user.id}</code>]", thumb="assets/thumb.jpg") await message.reply_video(
path,
caption=f"<code>{os.path.basename(path)}</code>\n\nUploaded for {message.from_user.mention} [<code>{message.from_user.id}</code>]",
thumb="assets/thumb.jpg",
)
await msg.delete() await msg.delete()
try: try:
os.remove(path) os.remove(path)

View file

@ -1,6 +1,9 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import random import random
import re import re
import os
import shutil import shutil
from apscheduler.schedulers.asyncio import AsyncIOScheduler from apscheduler.schedulers.asyncio import AsyncIOScheduler
@ -9,21 +12,22 @@ from pyrogram.errors import PeerIdInvalid, UserNotParticipant
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app from misskaty import app
from .web_scraper import SCRAP_DICT, data_kuso from misskaty.core.decorator.errors import capture_err
from .pypi_search import PYPI_DICT
from .ytdl_plugins import YT_DB
from utils import temp
from misskaty.core.decorator.permissions import admins_in_chat from misskaty.core.decorator.permissions import admins_in_chat
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
from misskaty.helper.time_gap import check_time_gap from misskaty.helper.time_gap import check_time_gap
from utils import temp
from .pypi_search import PYPI_DICT
from .web_scraper import SCRAP_DICT, data_kuso
from .ytdl_plugins import YT_DB
chat = [-1001128045651, -1001255283935, -1001455886928] chat = [-1001128045651, -1001255283935, -1001455886928]
REQUEST_DB = {} REQUEST_DB = {}
@app.on_message(filters.regex(r"alamu'?ala[iy]ku+m", re.I) & filters.chat(chat)) @app.on_message(filters.regex(r"alamu'?ala[iy]ku+m", re.I) & filters.chat(chat))
async def start(_, message): async def salamregex(_, message):
await message.reply_text(text=f"Wa'alaikumsalam {message.from_user.mention} 😇") await message.reply_text(text=f"Wa'alaikumsalam {message.from_user.mention} 😇")
@ -126,7 +130,7 @@ async def clear_reqdict():
# @app.on_message(filters.regex(r"makasi|thank|terimakasih|terima kasih|mksh", re.I) & filters.chat(chat)) # @app.on_message(filters.regex(r"makasi|thank|terimakasih|terima kasih|mksh", re.I) & filters.chat(chat))
async def start(_, message): async def thankregex(_, message):
pesan = [ pesan = [
f"Sama-sama {message.from_user.first_name}", f"Sama-sama {message.from_user.first_name}",
f"You're Welcome {message.from_user.first_name}", f"You're Welcome {message.from_user.first_name}",

View file

@ -25,11 +25,16 @@ import re
from pyrogram import filters from pyrogram import filters
from database.filters_db import delete_filter, get_filter, get_filters_names, save_filter from database.filters_db import (
delete_filter,
get_filter,
get_filters_names,
save_filter,
)
from misskaty import app from misskaty import app
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import adminsOnly from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb from misskaty.core.keyboard import ikb
from misskaty.helper.functions import extract_text_and_keyb from misskaty.helper.functions import extract_text_and_keyb
@ -47,7 +52,10 @@ You can use markdown or html to save text too.
@ratelimiter @ratelimiter
async def save_filters(_, m): async def save_filters(_, m):
if len(m.command) == 1 or not m.reply_to_message: if len(m.command) == 1 or not m.reply_to_message:
return await m.reply_msg("**Usage:**\nReply to a text or sticker with /addfilter [FILTER_NAME] to save it.", del_in=6) return await m.reply_msg(
"**Usage:**\nReply to a text or sticker with /addfilter [FILTER_NAME] to save it.",
del_in=6,
)
if not m.reply_to_message.text and not m.reply_to_message.sticker: if not m.reply_to_message.text and not m.reply_to_message.sticker:
return await m.reply_msg("__**You can only save text or stickers in filters for now.**__") return await m.reply_msg("__**You can only save text or stickers in filters for now.**__")
name = m.text.split(None, 1)[1].strip() name = m.text.split(None, 1)[1].strip()

View file

@ -6,9 +6,9 @@ from PIL import Image, ImageDraw, ImageFont
from pyrogram import filters from pyrogram import filters
from misskaty import app from misskaty import app
from misskaty.helper.localization import use_chat_lang
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
@ -160,13 +160,13 @@ async def memify(client, message):
hapus(png) hapus(png)
except: except:
pass pass
await message.reply(f"ERROR: {err}") await message.reply_msg(f"ERROR: {err}")
else: else:
await message.reply("Gunakan command <b>/mmf <text></b> dengan reply ke sticker, pisahkan dengan ; untuk membuat posisi text dibawah.") await message.reply_msg("Gunakan command <b>/mmf <text></b> dengan reply ke sticker, pisahkan dengan ; untuk membuat posisi text dibawah.")
@app.on_message(filters.command(["dice"], COMMAND_HANDLER)) @app.on_message(filters.command(["dice"], COMMAND_HANDLER))
@use_chat_lang() @use_chat_lang()
async def dice(c, m, strings): async def dice(c, m, strings):
dices = await c.send_dice(m.chat.id, reply_to_message_id=m.id) dices = await c.send_dice(m.chat.id, reply_to_message_id=m.id)
await dices.reply_text(strings("result").format(number=dices.dice.value), quote=True) await dices.reply_msg(strings("result").format(number=dices.dice.value), quote=True)

View file

@ -4,23 +4,22 @@
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
import math
import os import os
import time import time
import math
from asyncio import gather, sleep from asyncio import gather, sleep
from datetime import datetime from datetime import datetime
from logging import getLogger from logging import getLogger
from pySmartDL import SmartDL
from urllib.parse import unquote from urllib.parse import unquote
from pyrogram import enums, filters, Client from pyrogram import Client, enums, filters
from pyrogram.errors import FloodWait from pyrogram.errors import FloodWait
from pyrogram.file_id import FileId from pyrogram.file_id import FileId
from pyrogram.types import InlineKeyboardMarkup, Message, CallbackQuery from pyrogram.types import Message
from pySmartDL import SmartDL
from misskaty import app from misskaty import app
from misskaty.core.decorator import ratelimiter, new_task from misskaty.core.decorator import new_task, ratelimiter
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.helper import is_url, progress_for_pyrogram, take_ss from misskaty.helper import is_url, progress_for_pyrogram, take_ss
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.helper.pyro_progress import humanbytes from misskaty.helper.pyro_progress import humanbytes
@ -109,7 +108,11 @@ async def genss(self: Client, ctx: Message, strings):
] ]
) )
await ctx.reply_msg( await ctx.reply_msg(
strings("up_msg").format(namma=ctx.from_user.mention, id=ctx.from_user.id, bot_uname=self.me.username), strings("up_msg").format(
namma=ctx.from_user.mention,
id=ctx.from_user.id,
bot_uname=self.me.username,
),
reply_to_message_id=ctx.id, reply_to_message_id=ctx.id,
) )
await pesan.delete() await pesan.delete()
@ -165,7 +168,11 @@ async def genss(self: Client, ctx: Message, strings):
] ]
) )
await ctx.reply_msg( await ctx.reply_msg(
strings("up_msg").format(namma=ctx.from_user.mention, id=ctx.from_user.id, bot_uname=self.me.username), strings("up_msg").format(
namma=ctx.from_user.mention,
id=ctx.from_user.id,
bot_uname=self.me.username,
),
reply_to_message_id=ctx.id, reply_to_message_id=ctx.id,
) )
await process.delete() await process.delete()

View file

@ -11,11 +11,11 @@ from pyrogram.types import ChatMemberUpdated, InlineKeyboardButton, InlineKeyboa
from database.users_chats_db import db from database.users_chats_db import db
from misskaty import BOT_USERNAME, app from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator import asyncify, capture_err from misskaty.core.decorator import asyncify, capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO, SUPPORT_CHAT from misskaty.vars import COMMAND_HANDLER, SUDO, SUPPORT_CHAT
from utils import temp from utils import temp
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
@ -43,7 +43,9 @@ def draw_multiple_line_text(image, text, font, text_start_height):
lines = textwrap.wrap(text, width=50) lines = textwrap.wrap(text, width=50)
for line in lines: for line in lines:
line_width, line_height = font.getsize(line) line_width, line_height = font.getsize(line)
draw.text(((image_width - line_width) / 2, y_text), line, font=font, fill="black") draw.text(
((image_width - line_width) / 2, y_text), line, font=font, fill="black"
)
y_text += line_height y_text += line_height
@ -53,9 +55,15 @@ def welcomepic(pic, user, chat, id, strings):
background = background.resize((1024, 500), Image.ANTIALIAS) background = background.resize((1024, 500), Image.ANTIALIAS)
pfp = Image.open(pic).convert("RGBA") pfp = Image.open(pic).convert("RGBA")
pfp = circle(pfp) pfp = circle(pfp)
pfp = pfp.resize((265, 265)) # Resizes the Profilepicture so it fits perfectly in the circle pfp = pfp.resize(
font = ImageFont.truetype("assets/Calistoga-Regular.ttf", 37) # <- Text Font of the Member Count. Change the text size for your preference (265, 265)
member_text = strings("welcpic_msg").format(userr=user, id=id) # <- Text under the Profilepicture with the Membercount ) # Resizes the Profilepicture so it fits perfectly in the circle
font = ImageFont.truetype(
"assets/Calistoga-Regular.ttf", 37
) # <- Text Font of the Member Count. Change the text size for your preference
member_text = strings("welcpic_msg").format(
userr=user, id=id
) # <- Text under the Profilepicture with the Membercount
draw_multiple_line_text(background, member_text, font, 395) draw_multiple_line_text(background, member_text, font, 395)
draw_multiple_line_text(background, chat, font, 47) draw_multiple_line_text(background, chat, font, 47)
ImageDraw.Draw(background).text( ImageDraw.Draw(background).text(
@ -65,15 +73,25 @@ def welcomepic(pic, user, chat, id, strings):
size=20, size=20,
align="right", align="right",
) )
background.paste(pfp, (379, 123), pfp) # Pastes the Profilepicture on the Background Image background.paste(
background.save(f"downloads/welcome#{id}.png") # Saves the finished Image in the folder with the filename pfp, (379, 123), pfp
) # Pastes the Profilepicture on the Background Image
background.save(
f"downloads/welcome#{id}.png"
) # Saves the finished Image in the folder with the filename
return f"downloads/welcome#{id}.png" return f"downloads/welcome#{id}.png"
@app.on_chat_member_updated(filters.group & filters.chat([-1001128045651, -1001777794636])) @app.on_chat_member_updated(
filters.group & filters.chat([-1001128045651, -1001777794636])
)
@use_chat_lang() @use_chat_lang()
async def member_has_joined(c: app, member: ChatMemberUpdated, strings): async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
if not member.new_chat_member or member.new_chat_member.status in {"banned", "left", "restricted"} or member.old_chat_member: if (
not member.new_chat_member
or member.new_chat_member.status in {"banned", "left", "restricted"}
or member.old_chat_member
):
return return
user = member.new_chat_member.user if member.new_chat_member else member.from_user user = member.new_chat_member.user if member.new_chat_member else member.from_user
if user.id in SUDO: if user.id in SUDO:
@ -92,15 +110,21 @@ async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
pass pass
mention = f"<a href='tg://user?id={user.id}'>{user.first_name}</a>" mention = f"<a href='tg://user?id={user.id}'>{user.first_name}</a>"
joined_date = datetime.fromtimestamp(time.time()).strftime("%Y.%m.%d %H:%M:%S") joined_date = datetime.fromtimestamp(time.time()).strftime("%Y.%m.%d %H:%M:%S")
first_name = f"{user.first_name} {user.last_name}" if user.last_name else user.first_name first_name = (
f"{user.first_name} {user.last_name}" if user.last_name else user.first_name
)
id = user.id id = user.id
dc = user.dc_id or "Member tanpa PP" dc = user.dc_id or "Member tanpa PP"
try: try:
pic = await app.download_media(user.photo.big_file_id, file_name=f"pp{user.id}.png") pic = await app.download_media(
user.photo.big_file_id, file_name=f"pp{user.id}.png"
)
except AttributeError: except AttributeError:
pic = "assets/profilepic.png" pic = "assets/profilepic.png"
try: try:
welcomeimg = await welcomepic(pic, user.first_name, member.chat.title, user.id, strings) welcomeimg = await welcomepic(
pic, user.first_name, member.chat.title, user.id, strings
)
temp.MELCOW[f"welcome-{member.chat.id}"] = await c.send_photo( temp.MELCOW[f"welcome-{member.chat.id}"] = await c.send_photo(
member.chat.id, member.chat.id,
photo=welcomeimg, photo=welcomeimg,
@ -111,19 +135,35 @@ async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
userspammer = "" userspammer = ""
# Spamwatch Detection # Spamwatch Detection
try: try:
headers = {"Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"} headers = {
apispamwatch = (await http.get(f"https://api.spamwat.ch/banlist/{user.id}", headers=headers)).json() "Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"
}
apispamwatch = (
await http.get(
f"https://api.spamwat.ch/banlist/{user.id}", headers=headers
)
).json()
if not apispamwatch.get("error"): if not apispamwatch.get("error"):
await app.ban_chat_member(member.chat.id, user.id, datetime.now() + timedelta(seconds=30)) await app.ban_chat_member(
userspammer += strings("spamwatch_msg").format(umention=user.mention, uid=user.id, reas=apispamwatch.get("reason")) member.chat.id, user.id, datetime.now() + timedelta(seconds=30)
)
userspammer += strings("spamwatch_msg").format(
umention=user.mention, uid=user.id, reas=apispamwatch.get("reason")
)
except Exception as err: except Exception as err:
LOGGER.error(f"ERROR in Spamwatch Detection. {err}") LOGGER.error(f"ERROR in Spamwatch Detection. {err}")
# Combot API Detection # Combot API Detection
try: try:
apicombot = (await http.get(f"https://api.cas.chat/check?user_id={user.id}")).json() apicombot = (
await http.get(f"https://api.cas.chat/check?user_id={user.id}")
).json()
if apicombot.get("ok") == "true": if apicombot.get("ok") == "true":
await app.ban_chat_member(member.chat.id, user.id, datetime.now() + timedelta(seconds=30)) await app.ban_chat_member(
userspammer += strings("combot_msg").format(umention=user.mention, uid=user.id) member.chat.id, user.id, datetime.now() + timedelta(seconds=30)
)
userspammer += strings("combot_msg").format(
umention=user.mention, uid=user.id
)
except Exception as err: except Exception as err:
LOGGER.error(f"ERROR in Combot API Detection. {err}") LOGGER.error(f"ERROR in Combot API Detection. {err}")
if userspammer != "": if userspammer != "":
@ -138,50 +178,72 @@ async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
@app.on_message(filters.new_chat_members & filters.group, group=4) @app.on_message(filters.new_chat_members & filters.group, group=4)
@use_chat_lang() @use_chat_lang()
async def greet_group(bot, message, strings): async def greet_group(bot, message, strings):
for u in message.new_chat_members: for u in message.new_chat_members:
try:
pic = await app.download_media(
u.photo.big_file_id, file_name=f"pp{u.id}.png"
)
except AttributeError:
pic = "assets/profilepic.png"
if (temp.MELCOW).get(f"welcome-{message.chat.id}") is not None:
try: try:
pic = await app.download_media(u.photo.big_file_id, file_name=f"pp{u.id}.png") await temp.MELCOW[f"welcome-{message.chat.id}"].delete()
except AttributeError:
pic = "assets/profilepic.png"
if (temp.MELCOW).get(f"welcome-{message.chat.id}") is not None:
try:
await temp.MELCOW[f"welcome-{message.chat.id}"].delete()
except:
pass
try:
welcomeimg = await welcomepic(pic, u.first_name, message.chat.title, u.id, strings)
temp.MELCOW[f"welcome-{message.chat.id}"] = await app.send_photo(
message.chat.id,
photo=welcomeimg,
caption=strings("capt_welc").format(umention=u.mention, uid=u.id, ttl=message.chat.title),
)
userspammer = ""
# Spamwatch Detection
try:
headers = {"Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"}
apispamwatch = (await http.get(f"https://api.spamwat.ch/banlist/{u.id}", headers=headers)).json()
if not apispamwatch.get("error"):
await app.ban_chat_member(message.chat.id, u.id, datetime.now() + timedelta(seconds=30))
userspammer += strings("spamwatch_msg").format(umention=u.mention, uid=u.id, reas=apispamwatch.get("reason"))
except Exception as err:
LOGGER.error(f"ERROR in Spamwatch Detection. {err}")
# Combot API Detection
try:
apicombot = (await http.get(f"https://api.cas.chat/check?user_id={u.id}")).json()
if apicombot.get("ok") == "true":
await app.ban_chat_member(message.chat.id, u.id, datetime.now() + timedelta(seconds=30))
userspammer += strings("combot_msg").format(umention=u.mention, uid=u.id)
except Exception as err:
LOGGER.error(f"ERROR in Combot API Detection. {err}")
if userspammer != "":
await bot.send_message(message.chat.id, userspammer)
except: except:
pass pass
try:
welcomeimg = await welcomepic(
pic, u.first_name, message.chat.title, u.id, strings
)
temp.MELCOW[f"welcome-{message.chat.id}"] = await app.send_photo(
message.chat.id,
photo=welcomeimg,
caption=strings("capt_welc").format(
umention=u.mention, uid=u.id, ttl=message.chat.title
),
)
userspammer = ""
# Spamwatch Detection
try: try:
os.remove(f"downloads/welcome#{u.id}.png") headers = {
os.remove(f"downloads/pp{u.id}.png") "Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"
except Exception: }
pass apispamwatch = (
await http.get(
f"https://api.spamwat.ch/banlist/{u.id}", headers=headers
)
).json()
if not apispamwatch.get("error"):
await app.ban_chat_member(
message.chat.id, u.id, datetime.now() + timedelta(seconds=30)
)
userspammer += strings("spamwatch_msg").format(
umention=u.mention, uid=u.id, reas=apispamwatch.get("reason")
)
except Exception as err:
LOGGER.error(f"ERROR in Spamwatch Detection. {err}")
# Combot API Detection
try:
apicombot = (
await http.get(f"https://api.cas.chat/check?user_id={u.id}")
).json()
if apicombot.get("ok") == "true":
await app.ban_chat_member(
message.chat.id, u.id, datetime.now() + timedelta(seconds=30)
)
userspammer += strings("combot_msg").format(
umention=u.mention, uid=u.id
)
except Exception as err:
LOGGER.error(f"ERROR in Combot API Detection. {err}")
if userspammer != "":
await bot.send_message(message.chat.id, userspammer)
except:
pass
try:
os.remove(f"downloads/welcome#{u.id}.png")
os.remove(f"downloads/pp{u.id}.png")
except Exception:
pass
@app.on_message(filters.command("leave") & filters.user(SUDO)) @app.on_message(filters.command("leave") & filters.user(SUDO))
@ -192,9 +254,11 @@ async def leave_a_chat(bot, message):
try: try:
chat = int(chat) chat = int(chat)
except: except:
chat = chat pass
try: try:
buttons = [[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]] buttons = [
[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]
]
reply_markup = InlineKeyboardMarkup(buttons) reply_markup = InlineKeyboardMarkup(buttons)
await bot.send_message( await bot.send_message(
chat_id=chat, chat_id=chat,
@ -220,7 +284,9 @@ async def gen_invite(bot, message):
try: try:
link = await bot.create_chat_invite_link(chat) link = await bot.create_chat_invite_link(chat)
except ChatAdminRequired: except ChatAdminRequired:
return await message.reply("Invite Link Generation Failed, Iam Not Having Sufficient Rights") return await message.reply(
"Invite Link Generation Failed, Iam Not Having Sufficient Rights"
)
except Exception as e: except Exception as e:
return await message.reply(f"Error {e}") return await message.reply(f"Error {e}")
await message.reply(f"Here is your Invite Link {link.invite_link}") await message.reply(f"Here is your Invite Link {link.invite_link}")
@ -235,12 +301,16 @@ async def adminlist(_, message):
try: try:
msg = await message.reply_msg(f"Getting admin list in {message.chat.title}..") msg = await message.reply_msg(f"Getting admin list in {message.chat.title}..")
administrators = [] administrators = []
async for m in app.get_chat_members(message.chat.id, filter=enums.ChatMembersFilter.ADMINISTRATORS): async for m in app.get_chat_members(
message.chat.id, filter=enums.ChatMembersFilter.ADMINISTRATORS
):
uname = f"@{m.user.username}" if m.user.username else "" uname = f"@{m.user.username}" if m.user.username else ""
administrators.append(f"{m.user.first_name} [{uname}]") administrators.append(f"{m.user.first_name} [{uname}]")
res = "".join(f"💠 {i}\n" for i in administrators) res = "".join(f"💠 {i}\n" for i in administrators)
return await msg.edit_msg(f"Admin in <b>{message.chat.title}</b> ({message.chat.id}):\n{res}") return await msg.edit_msg(
f"Admin in <b>{message.chat.title}</b> ({message.chat.id}):\n{res}"
)
except Exception as e: except Exception as e:
await message.reply(f"ERROR: {str(e)}") await message.reply(f"ERROR: {str(e)}")
@ -259,7 +329,9 @@ async def kickme(_, message):
await message.reply_text(txt) await message.reply_text(txt)
await message.chat.unban_member(message.from_user.id) await message.chat.unban_member(message.from_user.id)
except RPCError as ef: except RPCError as ef:
await message.reply_text(f"Sepertinya ada error, silahkan report ke owner saya. \nERROR: {str(ef)}") await message.reply_text(
f"Sepertinya ada error, silahkan report ke owner saya. \nERROR: {str(ef)}"
)
except Exception as err: except Exception as err:
await message.reply(f"ERROR: {err}") await message.reply(f"ERROR: {err}")

View file

@ -1,25 +1,40 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import json import json
import logging import logging
import re import re
import traceback
from bs4 import BeautifulSoup
from urllib.parse import quote_plus from urllib.parse import quote_plus
from utils import demoji from bs4 import BeautifulSoup
from deep_translator import GoogleTranslator from deep_translator import GoogleTranslator
from pykeyboard import InlineButton, InlineKeyboard from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import filters, enums, Client from pyrogram import Client, enums, filters
from pyrogram.errors import MediaEmpty, MessageNotModified, PhotoInvalidDimensions, WebpageMediaEmpty, MessageIdInvalid from pyrogram.errors import (
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message, CallbackQuery MediaCaptionTooLong,
MediaEmpty,
MessageIdInvalid,
MessageNotModified,
PhotoInvalidDimensions,
WebpageMediaEmpty,
)
from pyrogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
InputMediaPhoto,
Message,
)
from database.imdb_db import * from database.imdb_db import *
from misskaty import BOT_USERNAME, app from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import http, get_random_string, search_jw, GENRES_EMOJI from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL from misskaty.helper import GENRES_EMOJI, get_random_string, http, search_jw
from misskaty.vars import COMMAND_HANDLER
from utils import demoji
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
LIST_CARI = {} LIST_CARI = {}
@ -32,10 +47,13 @@ headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWe
@ratelimiter @ratelimiter
async def imdb_choose(self: Client, ctx: Message): async def imdb_choose(self: Client, ctx: Message):
if len(ctx.command) == 1: if len(ctx.command) == 1:
return await ctx.reply_msg(f" Please add query after CMD!\nEx: <code>/{ctx.command[0]} Jurassic World</code>", del_in=5) return await ctx.reply_msg(
f" Please add query after CMD!\nEx: <code>/{ctx.command[0]} Jurassic World</code>",
del_in=5,
)
if ctx.sender_chat: if ctx.sender_chat:
return await ctx.reply_msg("This feature not supported for channel..", del_in=5) return await ctx.reply_msg("This feature not supported for channel..", del_in=5)
kuery = ctx.input kuery = ctx.text.split(" ", 1)[1]
is_imdb, lang = await is_imdbset(ctx.from_user.id) is_imdb, lang = await is_imdbset(ctx.from_user.id)
if is_imdb: if is_imdb:
if lang == "eng": if lang == "eng":
@ -61,12 +79,16 @@ async def imdb_choose(self: Client, ctx: Message):
await msg.wait_for_click(from_user_id=ctx.from_user.id, timeout=30) await msg.wait_for_click(from_user_id=ctx.from_user.id, timeout=30)
except ListenerTimeout: except ListenerTimeout:
del LIST_CARI[ranval] del LIST_CARI[ranval]
await msg.edit_caption("😶‍🌫️ Callback Query Timeout. Task Has Been Canceled!") try:
await msg.edit_caption("😶‍🌫️ Callback Query Timeout. Task Has Been Canceled!")
except MessageIdInvalid:
pass
@app.on_callback_query(filters.regex("^imdbset")) @app.on_callback_query(filters.regex("^imdbset"))
@ratelimiter @ratelimiter
async def imdbsetlang(self: Client, query: CallbackQuery): @capture_err
async def imdblangset(self: Client, query: CallbackQuery):
i, uid = query.data.split("#") i, uid = query.data.split("#")
if query.from_user.id != int(uid): if query.from_user.id != int(uid):
return await query.answer("⚠️ Access Denied!", True) return await query.answer("⚠️ Access Denied!", True)
@ -81,16 +103,17 @@ async def imdbsetlang(self: Client, query: CallbackQuery):
buttons.row(InlineButton("❌ Close", f"close#{query.from_user.id}")) buttons.row(InlineButton("❌ Close", f"close#{query.from_user.id}"))
msg = await query.message.edit_caption("<i>Please select available language below..</i>", reply_markup=buttons) msg = await query.message.edit_caption("<i>Please select available language below..</i>", reply_markup=buttons)
try: try:
await msg.wait_for_click( await msg.wait_for_click(from_user_id=int(uid), timeout=30)
from_user_id=int(uid),
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_caption("😶‍🌫️ Callback Query Timeout. Task Has Been Canceled!") try:
await msg.edit_caption("😶‍🌫️ Callback Query Timeout. Task Has Been Canceled!")
except MessageIdInvalid:
pass
@app.on_callback_query(filters.regex("^setimdb")) @app.on_callback_query(filters.regex("^setimdb"))
@ratelimiter @ratelimiter
@capture_err
async def imdbsetlang(self: Client, query: CallbackQuery): async def imdbsetlang(self: Client, query: CallbackQuery):
i, lang, uid = query.data.split("#") i, lang, uid = query.data.split("#")
if query.from_user.id != int(uid): if query.from_user.id != int(uid):
@ -119,7 +142,10 @@ async def imdb_search_id(kueri, message):
msg = "" msg = ""
buttons = InlineKeyboard(row_width=4) buttons = InlineKeyboard(row_width=4)
try: try:
r = await http.get(f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json", headers=headers) r = await http.get(
f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json",
headers=headers,
)
res = r.json().get("d") res = r.json().get("d")
if not res: if not res:
return await k.edit_caption(f"⛔️ Tidak ditemukan hasil untuk kueri: <code>{kueri}</code>") return await k.edit_caption(f"⛔️ Tidak ditemukan hasil untuk kueri: <code>{kueri}</code>")
@ -156,12 +182,12 @@ async def imdb_search_id(kueri, message):
buttons.add(*BTN) buttons.add(*BTN)
msg = await k.edit_caption(msg, reply_markup=buttons) msg = await k.edit_caption(msg, reply_markup=buttons)
try: try:
await msg.wait_for_click( await msg.wait_for_click(from_user_id=message.from_user.id, timeout=30)
from_user_id=message.from_user.id,
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_caption("😶‍🌫️ Waktu Habis. Task Telah Dibatalkan!") try:
await msg.edit_caption("😶‍🌫️ Waktu Habis. Task Telah Dibatalkan!")
except MessageIdInvalid:
pass
except Exception as err: except Exception as err:
await k.edit_caption(f"Ooppss, gagal mendapatkan daftar judul di IMDb. Mungkin terkena rate limit atau down.\n\n<b>ERROR:</b> <code>{err}</code>") await k.edit_caption(f"Ooppss, gagal mendapatkan daftar judul di IMDb. Mungkin terkena rate limit atau down.\n\n<b>ERROR:</b> <code>{err}</code>")
@ -176,7 +202,10 @@ async def imdb_search_en(kueri, message):
msg = "" msg = ""
buttons = InlineKeyboard(row_width=4) buttons = InlineKeyboard(row_width=4)
try: try:
r = await http.get(f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json", headers=headers) r = await http.get(
f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json",
headers=headers,
)
res = r.json().get("d") res = r.json().get("d")
if not res: if not res:
return await k.edit_caption(f"⛔️ Result not found for keywords: <code>{kueri}</code>") return await k.edit_caption(f"⛔️ Result not found for keywords: <code>{kueri}</code>")
@ -213,18 +242,19 @@ async def imdb_search_en(kueri, message):
buttons.add(*BTN) buttons.add(*BTN)
msg = await k.edit_caption(msg, reply_markup=buttons) msg = await k.edit_caption(msg, reply_markup=buttons)
try: try:
await msg.wait_for_click( await msg.wait_for_click(from_user_id=message.from_user.id, timeout=30)
from_user_id=message.from_user.id,
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_caption("😶‍🌫️ Timeout. Task Has Been Cancelled!") try:
await msg.edit_caption("😶‍🌫️ Timeout. Task Has Been Cancelled!")
except MessageIdInvalid:
pass
except Exception as err: except Exception as err:
await k.edit_caption(f"Failed when requesting movies title. Maybe got rate limit or down.\n\n<b>ERROR:</b> <code>{err}</code>") await k.edit_caption(f"Failed when requesting movies title. Maybe got rate limit or down.\n\n<b>ERROR:</b> <code>{err}</code>")
@app.on_callback_query(filters.regex("^imdbcari")) @app.on_callback_query(filters.regex("^imdbcari"))
@ratelimiter @ratelimiter
@capture_err
async def imdbcari(self: Client, query: CallbackQuery): async def imdbcari(self: Client, query: CallbackQuery):
BTN = [] BTN = []
i, lang, msg, uid = query.data.split("#") i, lang, msg, uid = query.data.split("#")
@ -240,7 +270,10 @@ async def imdbcari(self: Client, query: CallbackQuery):
msg = "" msg = ""
buttons = InlineKeyboard(row_width=4) buttons = InlineKeyboard(row_width=4)
try: try:
r = await http.get(f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json", headers=headers) r = await http.get(
f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json",
headers=headers,
)
res = r.json().get("d") res = r.json().get("d")
if not res: if not res:
return await query.message.edit_caption(f"⛔️ Tidak ditemukan hasil untuk kueri: <code>{kueri}</code>") return await query.message.edit_caption(f"⛔️ Tidak ditemukan hasil untuk kueri: <code>{kueri}</code>")
@ -266,12 +299,12 @@ async def imdbcari(self: Client, query: CallbackQuery):
buttons.add(*BTN) buttons.add(*BTN)
msg = await query.message.edit_caption(msg, reply_markup=buttons) msg = await query.message.edit_caption(msg, reply_markup=buttons)
try: try:
await msg.wait_for_click( await msg.wait_for_click(from_user_id=int(uid), timeout=30)
from_user_id=int(uid),
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_caption("😶‍🌫️ Waktu Habis. Task Telah Dibatalkan!") try:
await msg.edit_caption("😶‍🌫️ Waktu Habis. Task Telah Dibatalkan!")
except MessageIdInvalid:
pass
except Exception as err: except Exception as err:
await query.message.edit_caption(f"Ooppss, gagal mendapatkan daftar judul di IMDb. Mungkin terkena rate limit atau down.\n\n<b>ERROR:</b> <code>{err}</code>") await query.message.edit_caption(f"Ooppss, gagal mendapatkan daftar judul di IMDb. Mungkin terkena rate limit atau down.\n\n<b>ERROR:</b> <code>{err}</code>")
else: else:
@ -286,7 +319,10 @@ async def imdbcari(self: Client, query: CallbackQuery):
msg = "" msg = ""
buttons = InlineKeyboard(row_width=4) buttons = InlineKeyboard(row_width=4)
try: try:
r = await http.get(f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json", headers=headers) r = await http.get(
f"https://v3.sg.media-imdb.com/suggestion/titles/x/{quote_plus(kueri)}.json",
headers=headers,
)
res = r.json().get("d") res = r.json().get("d")
if not res: if not res:
return await query.message.edit_caption(f"⛔️ Result not found for keywords: <code>{kueri}</code>") return await query.message.edit_caption(f"⛔️ Result not found for keywords: <code>{kueri}</code>")
@ -312,18 +348,19 @@ async def imdbcari(self: Client, query: CallbackQuery):
buttons.add(*BTN) buttons.add(*BTN)
msg = await query.message.edit_caption(msg, reply_markup=buttons) msg = await query.message.edit_caption(msg, reply_markup=buttons)
try: try:
await msg.wait_for_click( await msg.wait_for_click(from_user_id=int(uid), timeout=30)
from_user_id=int(uid),
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_caption("😶‍🌫️ Timeout. Task Has Been Cancelled!") try:
await msg.edit_caption("😶‍🌫️ Timeout. Task Has Been Cancelled!")
except MessageIdInvalid:
pass
except Exception as err: except Exception as err:
await query.message.edit_caption(f"Failed when requesting movies title. Maybe got rate limit or down.\n\n<b>ERROR:</b> <code>{err}</code>") await query.message.edit_caption(f"Failed when requesting movies title. Maybe got rate limit or down.\n\n<b>ERROR:</b> <code>{err}</code>")
@app.on_callback_query(filters.regex("^imdbres_id")) @app.on_callback_query(filters.regex("^imdbres_id"))
@ratelimiter @ratelimiter
@capture_err
async def imdb_id_callback(self: Client, query: CallbackQuery): async def imdb_id_callback(self: Client, query: CallbackQuery):
i, userid, movie = query.data.split("#") i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid): if query.from_user.id != int(userid):
@ -372,7 +409,7 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
for i in directors: for i in directors:
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
director += f"<a href='https://www.imdb.com{url}'>{name}</a>, " director += f"<a href='{url}'>{name}</a>, "
director = director[:-2] director = director[:-2]
res_str += f"<b>Sutradara:</b> {director}\n" res_str += f"<b>Sutradara:</b> {director}\n"
if creators := r_json.get("creator"): if creators := r_json.get("creator"):
@ -381,7 +418,7 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
if i["@type"] == "Person": if i["@type"] == "Person":
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
creator += f"<a href='https://www.imdb.com{url}'>{name}</a>, " creator += f"<a href='{url}'>{name}</a>, "
creator = creator[:-2] creator = creator[:-2]
res_str += f"<b>Penulis:</b> {creator}\n" res_str += f"<b>Penulis:</b> {creator}\n"
if actor := r_json.get("actor"): if actor := r_json.get("actor"):
@ -389,7 +426,7 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
for i in actor: for i in actor:
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
actors += f"<a href='https://www.imdb.com{url}'>{name}</a>, " actors += f"<a href='{url}'>{name}</a>, "
actors = actors[:-2] actors = actors[:-2]
res_str += f"<b>Pemeran:</b> {actors}\n\n" res_str += f"<b>Pemeran:</b> {actors}\n\n"
if deskripsi := r_json.get("description"): if deskripsi := r_json.get("description"):
@ -416,33 +453,38 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
markup = InlineKeyboardMarkup( markup = InlineKeyboardMarkup(
[ [
[ [
InlineKeyboardButton("🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"), InlineKeyboardButton("🎬 Open IMDB", url=url),
InlineKeyboardButton("▶️ Trailer", url=trailer_url), InlineKeyboardButton("▶️ Trailer", url=trailer_url),
] ]
] ]
) )
else: else:
markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}")]]) markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Open IMDB", url=url)]])
if thumb := r_json.get("image"): if thumb := r_json.get("image"):
try: try:
await query.message.edit_media(InputMediaPhoto(thumb, caption=res_str, parse_mode=enums.ParseMode.HTML), reply_markup=markup) await query.message.edit_media(
InputMediaPhoto(thumb, caption=res_str, parse_mode=enums.ParseMode.HTML),
reply_markup=markup,
)
except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty): except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty):
poster = thumb.replace(".jpg", "._V1_UX360.jpg") poster = thumb.replace(".jpg", "._V1_UX360.jpg")
await query.message.edit_media(InputMediaPhoto(poster, caption=res_str, parse_mode=enums.ParseMode.HTML), reply_markup=markup) await query.message.edit_media(
InputMediaPhoto(poster, caption=res_str, parse_mode=enums.ParseMode.HTML),
reply_markup=markup,
)
except MediaCaptionTooLong:
await query.message.reply(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
except Exception: except Exception:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup) await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
else: else:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup) await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
except (MessageNotModified, MessageIdInvalid): except (MessageNotModified, MessageIdInvalid):
pass pass
except Exception as exc:
err = traceback.format_exc(limit=20)
await query.message.edit_caption(f"<b>ERROR:</b>\n<code>{exc}</code>\n<b>Full Error:</b> <code>{err}</code>\n\nSilahkan lapor ke owner detail errornya dengan lengkap, atau laporan error akan diabaikan.")
await app.send_message(LOG_CHANNEL, f"ERROR getting IMDb Detail in Indonesia:\n<code>{str(err)}</code>")
@app.on_callback_query(filters.regex("^imdbres_en")) @app.on_callback_query(filters.regex("^imdbres_en"))
@ratelimiter @ratelimiter
@capture_err
async def imdb_en_callback(self: Client, query: CallbackQuery): async def imdb_en_callback(self: Client, query: CallbackQuery):
i, userid, movie = query.data.split("#") i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid): if query.from_user.id != int(userid):
@ -491,7 +533,7 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
for i in directors: for i in directors:
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
director += f"<a href='https://www.imdb.com{url}'>{name}</a>, " director += f"<a href='{url}'>{name}</a>, "
director = director[:-2] director = director[:-2]
res_str += f"<b>Director:</b> {director}\n" res_str += f"<b>Director:</b> {director}\n"
if creators := r_json.get("creator"): if creators := r_json.get("creator"):
@ -500,7 +542,7 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
if i["@type"] == "Person": if i["@type"] == "Person":
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
creator += f"<a href='https://www.imdb.com{url}'>{name}</a>, " creator += f"<a href='{url}'>{name}</a>, "
creator = creator[:-2] creator = creator[:-2]
res_str += f"<b>Writer:</b> {creator}\n" res_str += f"<b>Writer:</b> {creator}\n"
if actor := r_json.get("actor"): if actor := r_json.get("actor"):
@ -508,7 +550,7 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
for i in actor: for i in actor:
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
actors += f"<a href='https://www.imdb.com{url}'>{name}</a>, " actors += f"<a href='{url}'>{name}</a>, "
actors = actors[:-2] actors = actors[:-2]
res_str += f"<b>Stars:</b> {actors}\n\n" res_str += f"<b>Stars:</b> {actors}\n\n"
if description := r_json.get("description"): if description := r_json.get("description"):
@ -534,26 +576,30 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
markup = InlineKeyboardMarkup( markup = InlineKeyboardMarkup(
[ [
[ [
InlineKeyboardButton("🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"), InlineKeyboardButton("🎬 Open IMDB", url=url),
InlineKeyboardButton("▶️ Trailer", url=trailer_url), InlineKeyboardButton("▶️ Trailer", url=trailer_url),
] ]
] ]
) )
else: else:
markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}")]]) markup = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Open IMDB", url=url)]])
if thumb := r_json.get("image"): if thumb := r_json.get("image"):
try: try:
await query.message.edit_media(InputMediaPhoto(thumb, caption=res_str, parse_mode=enums.ParseMode.HTML), reply_markup=markup) await query.message.edit_media(
InputMediaPhoto(thumb, caption=res_str, parse_mode=enums.ParseMode.HTML),
reply_markup=markup,
)
except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty): except (MediaEmpty, PhotoInvalidDimensions, WebpageMediaEmpty):
poster = thumb.replace(".jpg", "._V1_UX360.jpg") poster = thumb.replace(".jpg", "._V1_UX360.jpg")
await query.message.edit_media(InputMediaPhoto(poster, caption=res_str, parse_mode=enums.ParseMode.HTML), reply_markup=markup) await query.message.edit_media(
InputMediaPhoto(poster, caption=res_str, parse_mode=enums.ParseMode.HTML),
reply_markup=markup,
)
except MediaCaptionTooLong:
await query.message.reply(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
except Exception: except Exception:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup) await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
else: else:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup) await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
except (MessageNotModified, MessageIdInvalid): except (MessageNotModified, MessageIdInvalid):
pass pass
except Exception as exc:
err = traceback.format_exc(limit=20)
await query.message.edit_caption(f"<b>ERROR:</b>\n<code>{exc}</code>\n<b>Full Error:</b> <code>{err}</code>\n\nPlease report to owner with detail of error, or your report will be ignored.")
await app.send_message(LOG_CHANNEL, f"ERROR getting IMDb Detail in Eng:\n<code>{str(err)}</code>")

View file

@ -1,3 +1,7 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import json import json
import re import re
import traceback import traceback
@ -8,7 +12,7 @@ from sys import version as pyver
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from deep_translator import GoogleTranslator from deep_translator import GoogleTranslator
from motor import version as mongover from motor import version as mongover
from pykeyboard import InlineKeyboard, InlineButton from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import __version__ as pyrover from pyrogram import __version__ as pyrover
from pyrogram import enums, filters from pyrogram import enums, filters
from pyrogram.errors import MessageIdInvalid, MessageNotModified from pyrogram.errors import MessageIdInvalid, MessageNotModified
@ -23,7 +27,7 @@ from pyrogram.types import (
from misskaty import BOT_USERNAME, app, user from misskaty import BOT_USERNAME, app, user
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import post_to_telegraph, http, GENRES_EMOJI, search_jw from misskaty.helper import GENRES_EMOJI, http, post_to_telegraph, search_jw
from misskaty.plugins.misc_tools import get_content from misskaty.plugins.misc_tools import get_content
from utils import demoji from utils import demoji
@ -47,7 +51,12 @@ LOGGER = getLogger()
async def inline_menu(_, inline_query: InlineQuery): async def inline_menu(_, inline_query: InlineQuery):
if inline_query.query.strip().lower().strip() == "": if inline_query.query.strip().lower().strip() == "":
buttons = InlineKeyboard(row_width=2) buttons = InlineKeyboard(row_width=2)
buttons.add(*[(InlineKeyboardButton(text=i, switch_inline_query_current_chat=i)) for i in keywords_list]) buttons.add(
*[
(InlineKeyboardButton(text=i, switch_inline_query_current_chat=i))
for i in keywords_list
]
)
btn = InlineKeyboard(row_width=2) btn = InlineKeyboard(row_width=2)
bot_state = "Alive" if await app.get_me() else "Dead" bot_state = "Alive" if await app.get_me() else "Dead"
@ -71,21 +80,27 @@ async def inline_menu(_, inline_query: InlineQuery):
InlineQueryResultArticle( InlineQueryResultArticle(
title="Inline Commands", title="Inline Commands",
description="Help Related To Inline Usage.", description="Help Related To Inline Usage.",
input_message_content=InputTextMessageContent("Click A Button To Get Started."), input_message_content=InputTextMessageContent(
"Click A Button To Get Started."
),
thumb_url="https://hamker.me/cy00x5x.png", thumb_url="https://hamker.me/cy00x5x.png",
reply_markup=buttons, reply_markup=buttons,
), ),
InlineQueryResultArticle( InlineQueryResultArticle(
title="Github Repo", title="Github Repo",
description="Github Repo of This Bot.", description="Github Repo of This Bot.",
input_message_content=InputTextMessageContent(f"<b>Github Repo @{BOT_USERNAME}</b>\n\nhttps://github.com/yasirarism/MissKatyPyro"), input_message_content=InputTextMessageContent(
f"<b>Github Repo @{BOT_USERNAME}</b>\n\nhttps://github.com/yasirarism/MissKatyPyro"
),
thumb_url="https://hamker.me/gjc9fo3.png", thumb_url="https://hamker.me/gjc9fo3.png",
), ),
InlineQueryResultArticle( InlineQueryResultArticle(
title="Alive", title="Alive",
description="Check Bot's Stats", description="Check Bot's Stats",
thumb_url="https://yt3.ggpht.com/ytc/AMLnZu-zbtIsllERaGYY8Aecww3uWUASPMjLUUEt7ecu=s900-c-k-c0x00ffffff-no-rj", thumb_url="https://yt3.ggpht.com/ytc/AMLnZu-zbtIsllERaGYY8Aecww3uWUASPMjLUUEt7ecu=s900-c-k-c0x00ffffff-no-rj",
input_message_content=InputTextMessageContent(msg, disable_web_page_preview=True), input_message_content=InputTextMessageContent(
msg, disable_web_page_preview=True
),
reply_markup=btn, reply_markup=btn,
), ),
] ]
@ -98,7 +113,10 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline", switch_pm_parameter="inline",
) )
kueri = inline_query.query.split(None, 1)[1].strip() kueri = inline_query.query.split(None, 1)[1].strip()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/61.0.3163.100 Safari/537.36"} headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/61.0.3163.100 Safari/537.36"
}
jsonapi = await http.get( jsonapi = await http.get(
"https://github.com/PaulSonOfLars/telegram-bot-api-spec/raw/main/api.json", "https://github.com/PaulSonOfLars/telegram-bot-api-spec/raw/main/api.json",
headers=headers, headers=headers,
@ -114,7 +132,10 @@ async def inline_menu(_, inline_query: InlineQuery):
buttons = InlineKeyboard() buttons = InlineKeyboard()
buttons.row( buttons.row(
InlineButton("Open Docs", url=link), InlineButton("Open Docs", url=link),
InlineButton("Search Again", switch_inline_query_current_chat=inline_query.query), InlineButton(
"Search Again",
switch_inline_query_current_chat=inline_query.query,
),
) )
buttons.row( buttons.row(
InlineButton("Give Coffee", url="https://yasirpedia.eu.org"), InlineButton("Give Coffee", url="https://yasirpedia.eu.org"),
@ -122,7 +143,7 @@ async def inline_menu(_, inline_query: InlineQuery):
returns = "".join(f"{i}, " for i in parsemethod[method]["returns"]) returns = "".join(f"{i}, " for i in parsemethod[method]["returns"])
msg = f"<b>{method}</b> (<code>{returns[:-2]}</code>)\n" msg = f"<b>{method}</b> (<code>{returns[:-2]}</code>)\n"
msg += f"{description}\n\n" msg += f"{description}\n\n"
msg += f"<b>Variables:</b>\n" msg += "<b>Variables:</b>\n"
if parsemethod[method].get("fields"): if parsemethod[method].get("fields"):
for i in parsemethod[method]["fields"]: for i in parsemethod[method]["fields"]:
msg += f"<code>{i['name']}</code> (<b>{i['types'][0]}</b>)\n<b>Required:</b> <code>{i['required']}</code>\n{i['description']}\n\n" msg += f"<code>{i['name']}</code> (<b>{i['types'][0]}</b>)\n<b>Required:</b> <code>{i['required']}</code>\n{i['description']}\n\n"
@ -152,14 +173,17 @@ async def inline_menu(_, inline_query: InlineQuery):
buttons = InlineKeyboard() buttons = InlineKeyboard()
buttons.row( buttons.row(
InlineButton("Open Docs", url=link), InlineButton("Open Docs", url=link),
InlineButton("Search Again", switch_inline_query_current_chat=inline_query.query), InlineButton(
"Search Again",
switch_inline_query_current_chat=inline_query.query,
),
) )
buttons.row( buttons.row(
InlineButton("Give Coffee", url="https://yasirpedia.eu.org"), InlineButton("Give Coffee", url="https://yasirpedia.eu.org"),
) )
msg = f"<b>{types}</b>\n" msg = f"<b>{types}</b>\n"
msg += f"{description}\n\n" msg += f"{description}\n\n"
msg += f"<b>Variables:</b>\n" msg += "<b>Variables:</b>\n"
if parsetypes[types].get("fields"): if parsetypes[types].get("fields"):
for i in parsetypes[types]["fields"]: for i in parsetypes[types]["fields"]:
msg += f"<code>{i['name']}</code> (<b>{i['types'][0]}</b>)\n<b>Required:</b> <code>{i['required']}</code>\n{i['description']}\n\n" msg += f"<code>{i['name']}</code> (<b>{i['types'][0]}</b>)\n<b>Required:</b> <code>{i['required']}</code>\n{i['description']}\n\n"
@ -199,15 +223,21 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline", switch_pm_parameter="inline",
) )
judul = inline_query.query.split(None, 1)[1].strip() judul = inline_query.query.split(None, 1)[1].strip()
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edge/107.0.1418.42"} headers = {
search_results = await http.get(f"https://www.google.com/search?q={judul}&num=20", headers=headers) "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edge/107.0.1418.42"
}
search_results = await http.get(
f"https://www.google.com/search?q={judul}&num=20", headers=headers
)
soup = BeautifulSoup(search_results.text, "lxml") soup = BeautifulSoup(search_results.text, "lxml")
data = [] data = []
for result in soup.find_all("div", class_="kvH3mc BToiNc UK95Uc"): for result in soup.find_all("div", class_="kvH3mc BToiNc UK95Uc"):
link = result.find("div", class_ ="yuRUbf").find("a").get("href") link = result.find("div", class_="yuRUbf").find("a").get("href")
title = result.find("div", class_ ="yuRUbf").find("h3").get_text() title = result.find("div", class_="yuRUbf").find("h3").get_text()
try: try:
snippet = result.find("div", class_="VwiC3b yXK7lf MUxGbd yDYNvb lyLwlc lEBKkf").get_text() snippet = result.find(
"div", class_="VwiC3b yXK7lf MUxGbd yDYNvb lyLwlc lEBKkf"
).get_text()
except: except:
snippet = "-" snippet = "-"
message_text = f"<a href='{link}'>{title}</a>\n" message_text = f"<a href='{link}'>{title}</a>\n"
@ -223,7 +253,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link, url=link,
description=snippet, description=snippet,
thumb_url="https://te.legra.ph/file/ed8ea62ae636793000bb4.jpg", thumb_url="https://te.legra.ph/file/ed8ea62ae636793000bb4.jpg",
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="Open Website", url=link)]]), reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton(text="Open Website", url=link)]]
),
) )
) )
await inline_query.answer( await inline_query.answer(
@ -250,7 +282,9 @@ async def inline_menu(_, inline_query: InlineQuery):
except Exception: # pylint: disable=broad-except except Exception: # pylint: disable=broad-except
inline_query.stop_propagation() inline_query.stop_propagation()
return return
namanya = f"{diaa.first_name} {diaa.last_name}" if diaa.last_name else diaa.first_name namanya = (
f"{diaa.first_name} {diaa.last_name}" if diaa.last_name else diaa.first_name
)
msg = f"<b>🏷 Name:</b> {namanya}\n<b>🆔 ID:</b> <code>{diaa.id}</code>\n" msg = f"<b>🏷 Name:</b> {namanya}\n<b>🆔 ID:</b> <code>{diaa.id}</code>\n"
if diaa.username: if diaa.username:
msg += f"<b>🌐 Username:</b> <code>@{diaa.username}</code>\n" msg += f"<b>🌐 Username:</b> <code>@{diaa.username}</code>\n"
@ -298,7 +332,11 @@ async def inline_menu(_, inline_query: InlineQuery):
) )
prvte_msg = InlineKeyboardMarkup( prvte_msg = InlineKeyboardMarkup(
[ [
[InlineKeyboardButton("Show Message 🔐", callback_data=f"prvtmsg({inline_query.id})")], [
InlineKeyboardButton(
"Show Message 🔐", callback_data=f"prvtmsg({inline_query.id})"
)
],
[ [
InlineKeyboardButton( InlineKeyboardButton(
"Destroy☠ this msg", "Destroy☠ this msg",
@ -307,8 +345,14 @@ async def inline_menu(_, inline_query: InlineQuery):
], ],
] ]
) )
mention = f"@{penerima.username}" if penerima.username else f"<a href='tg://user?id={penerima.id}'>{penerima.first_name}</a>" mention = (
msg_c = f"🔒 A <b>private message</b> to {mention} [<code>{penerima.id}</code>], " f"@{penerima.username}"
if penerima.username
else f"<a href='tg://user?id={penerima.id}'>{penerima.first_name}</a>"
)
msg_c = (
f"🔒 A <b>private message</b> to {mention} [<code>{penerima.id}</code>], "
)
msg_c += "Only he/she can open it." msg_c += "Only he/she can open it."
results = [ results = [
InlineQueryResultArticle( InlineQueryResultArticle(
@ -328,7 +372,9 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline", switch_pm_parameter="inline",
) )
query = inline_query.query.split(None, 1)[1].strip() query = inline_query.query.split(None, 1)[1].strip()
search_results = await http.get(f"https://api.github.com/search/repositories?q={query}") search_results = await http.get(
f"https://api.github.com/search/repositories?q={query}"
)
srch_results = json.loads(search_results.text) srch_results = json.loads(search_results.text)
item = srch_results.get("items") item = srch_results.get("items")
data = [] data = []
@ -351,7 +397,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link, url=link,
description=deskripsi, description=deskripsi,
thumb_url="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png", thumb_url="https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png",
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="Open Github Link", url=link)]]), reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton(text="Open Github Link", url=link)]]
),
) )
) )
await inline_query.answer( await inline_query.answer(
@ -391,7 +439,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link, url=link,
description=deskripsi, description=deskripsi,
thumb_url="https://raw.githubusercontent.com/github/explore/666de02829613e0244e9441b114edb85781e972c/topics/pip/pip.png", thumb_url="https://raw.githubusercontent.com/github/explore/666de02829613e0244e9441b114edb85781e972c/topics/pip/pip.png",
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="Open Link", url=link)]]), reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton(text="Open Link", url=link)]]
),
) )
) )
await inline_query.answer( await inline_query.answer(
@ -410,7 +460,9 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline", switch_pm_parameter="inline",
) )
judul = inline_query.query.split(None, 1)[1].strip() judul = inline_query.query.split(None, 1)[1].strip()
search_results = await http.get(f"https://api.abir-hasan.tk/youtube?query={judul}") search_results = await http.get(
f"https://api.abir-hasan.tk/youtube?query={judul}"
)
srch_results = json.loads(search_results.text) srch_results = json.loads(search_results.text)
asroe = srch_results.get("results") asroe = srch_results.get("results")
oorse = [] oorse = []
@ -422,7 +474,9 @@ async def inline_menu(_, inline_query: InlineQuery):
durasi = sraeo.get("accessibility").get("duration") durasi = sraeo.get("accessibility").get("duration")
publishTime = sraeo.get("publishedTime") publishTime = sraeo.get("publishedTime")
try: try:
deskripsi = "".join(f"{i['text']} " for i in sraeo.get("descriptionSnippet")) deskripsi = "".join(
f"{i['text']} " for i in sraeo.get("descriptionSnippet")
)
except: except:
deskripsi = "-" deskripsi = "-"
message_text = f"<a href='{link}'>{title}</a>\n" message_text = f"<a href='{link}'>{title}</a>\n"
@ -441,7 +495,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link, url=link,
description=deskripsi, description=deskripsi,
thumb_url=thumb, thumb_url=thumb,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="Watch Video 📹", url=link)]]), reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton(text="Watch Video 📹", url=link)]]
),
) )
) )
await inline_query.answer( await inline_query.answer(
@ -460,7 +516,9 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline", switch_pm_parameter="inline",
) )
movie_name = inline_query.query.split(None, 1)[1].strip() movie_name = inline_query.query.split(None, 1)[1].strip()
search_results = await http.get(f"https://yasirapi.eu.org/imdb-search?q={movie_name}") search_results = await http.get(
f"https://yasirapi.eu.org/imdb-search?q={movie_name}"
)
res = json.loads(search_results.text).get("result") res = json.loads(search_results.text).get("result")
oorse = [] oorse = []
for midb in res: for midb in res:
@ -469,7 +527,11 @@ async def inline_menu(_, inline_query: InlineQuery):
stars = midb.get("s", "") stars = midb.get("s", "")
imdb_url = f"https://imdb.com/title/{midb.get('id')}" imdb_url = f"https://imdb.com/title/{midb.get('id')}"
year = f"({midb.get('y', '')})" year = f"({midb.get('y', '')})"
image_url = midb.get("i").get("imageUrl").replace(".jpg", "._V1_UX360.jpg") if midb.get("i") else "https://te.legra.ph/file/e263d10ff4f4426a7c664.jpg" image_url = (
midb.get("i").get("imageUrl").replace(".jpg", "._V1_UX360.jpg")
if midb.get("i")
else "https://te.legra.ph/file/e263d10ff4f4426a7c664.jpg"
)
caption = f"<a href='{image_url}'>🎬</a>" caption = f"<a href='{image_url}'>🎬</a>"
caption += f"<a href='{imdb_url}'>{title} {year}</a>" caption += f"<a href='{imdb_url}'>{title} {year}</a>"
oorse.append( oorse.append(
@ -543,41 +605,78 @@ async def imdb_inl(_, query):
i, user, movie = query.data.split("#") i, user, movie = query.data.split("#")
if user == f"{query.from_user.id}": if user == f"{query.from_user.id}":
try: try:
await query.edit_message_caption("⏳ <i>Permintaan kamu sedang diproses.. </i>") await query.edit_message_caption(
"⏳ <i>Permintaan kamu sedang diproses.. </i>"
)
url = f"https://www.imdb.com/title/{movie}/" url = f"https://www.imdb.com/title/{movie}/"
resp = await get_content(url) resp = await get_content(url)
sop = BeautifulSoup(resp, "lxml") sop = BeautifulSoup(resp, "lxml")
r_json = json.loads(sop.find("script", attrs={"type": "application/ld+json"}).contents[0]) r_json = json.loads(
sop.find("script", attrs={"type": "application/ld+json"}).contents[0]
)
ott = await search_jw(r_json["name"], "en_ID") ott = await search_jw(r_json["name"], "en_ID")
res_str = "" res_str = ""
typee = r_json.get("@type", "") typee = r_json.get("@type", "")
tahun = re.findall(r"\d{4}\W\d{4}|\d{4}-?", sop.title.text)[0] if re.findall(r"\d{4}\W\d{4}|\d{4}-?", sop.title.text) else "N/A" tahun = (
re.findall(r"\d{4}\W\d{4}|\d{4}-?", sop.title.text)[0]
if re.findall(r"\d{4}\W\d{4}|\d{4}-?", sop.title.text)
else "N/A"
)
res_str += f"<b>📹 Judul:</b> <a href='{url}'>{r_json['name']} [{tahun}]</a> (<code>{typee}</code>)\n" res_str += f"<b>📹 Judul:</b> <a href='{url}'>{r_json['name']} [{tahun}]</a> (<code>{typee}</code>)\n"
if r_json.get("alternateName"): if r_json.get("alternateName"):
res_str += f"<b>📢 AKA:</b> <code>{r_json.get('alternateName')}</code>\n\n" res_str += (
f"<b>📢 AKA:</b> <code>{r_json.get('alternateName')}</code>\n\n"
)
else: else:
res_str += "\n" res_str += "\n"
if durasi := sop.select('li[data-testid="title-techspec_runtime"]'): if durasi := sop.select('li[data-testid="title-techspec_runtime"]'):
durasi = durasi[0].find(class_="ipc-metadata-list-item__content-container").text durasi = (
durasi[0]
.find(class_="ipc-metadata-list-item__content-container")
.text
)
res_str += f"<b>Durasi:</b> <code>{GoogleTranslator('auto', 'id').translate(durasi)}</code>\n" res_str += f"<b>Durasi:</b> <code>{GoogleTranslator('auto', 'id').translate(durasi)}</code>\n"
if r_json.get("contentRating"): if r_json.get("contentRating"):
res_str += f"<b>Kategori:</b> <code>{r_json['contentRating']}</code> \n" res_str += f"<b>Kategori:</b> <code>{r_json['contentRating']}</code> \n"
if r_json.get("aggregateRating"): if r_json.get("aggregateRating"):
res_str += f"<b>Peringkat:</b> <code>{r_json['aggregateRating']['ratingValue']}⭐️ dari {r_json['aggregateRating']['ratingCount']} pengguna</code> \n" res_str += f"<b>Peringkat:</b> <code>{r_json['aggregateRating']['ratingValue']}⭐️ dari {r_json['aggregateRating']['ratingCount']} pengguna</code> \n"
if release := sop.select('li[data-testid="title-details-releasedate"]'): if release := sop.select('li[data-testid="title-details-releasedate"]'):
rilis = release[0].find(class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link").text rilis = (
rilis_url = release[0].find(class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link")["href"] release[0]
.find(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
.text
)
rilis_url = release[0].find(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)["href"]
res_str += f"<b>Rilis:</b> <a href='https://www.imdb.com{rilis_url}'>{rilis}</a>\n" res_str += f"<b>Rilis:</b> <a href='https://www.imdb.com{rilis_url}'>{rilis}</a>\n"
if r_json.get("genre"): if r_json.get("genre"):
genre = "".join(f"{GENRES_EMOJI[i]} #{i.replace('-', '_').replace(' ', '_')}, " if i in GENRES_EMOJI else f"#{i.replace('-', '_').replace(' ', '_')}, " for i in r_json["genre"]) genre = "".join(
f"{GENRES_EMOJI[i]} #{i.replace('-', '_').replace(' ', '_')}, "
if i in GENRES_EMOJI
else f"#{i.replace('-', '_').replace(' ', '_')}, "
for i in r_json["genre"]
)
genre = genre[:-2] genre = genre[:-2]
res_str += f"<b>Genre:</b> {genre}\n" res_str += f"<b>Genre:</b> {genre}\n"
if negara := sop.select('li[data-testid="title-details-origin"]'): if negara := sop.select('li[data-testid="title-details-origin"]'):
country = "".join(f"{demoji(country.text)} #{country.text.replace(' ', '_').replace('-', '_')}, " for country in negara[0].findAll(class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link")) country = "".join(
f"{demoji(country.text)} #{country.text.replace(' ', '_').replace('-', '_')}, "
for country in negara[0].findAll(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
)
country = country[:-2] country = country[:-2]
res_str += f"<b>Negara:</b> {country}\n" res_str += f"<b>Negara:</b> {country}\n"
if bahasa := sop.select('li[data-testid="title-details-languages"]'): if bahasa := sop.select('li[data-testid="title-details-languages"]'):
language = "".join(f"#{lang.text.replace(' ', '_').replace('-', '_')}, " for lang in bahasa[0].findAll(class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link")) language = "".join(
f"#{lang.text.replace(' ', '_').replace('-', '_')}, "
for lang in bahasa[0].findAll(
class_="ipc-metadata-list-item__list-content-item ipc-metadata-list-item__list-content-item--link"
)
)
language = language[:-2] language = language[:-2]
res_str += f"<b>Bahasa:</b> {language}\n" res_str += f"<b>Bahasa:</b> {language}\n"
res_str += "\n<b>🙎 Info Cast:</b>\n" res_str += "\n<b>🙎 Info Cast:</b>\n"
@ -586,7 +685,7 @@ async def imdb_inl(_, query):
for i in r_json["director"]: for i in r_json["director"]:
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
director += f"<a href='https://www.imdb.com{url}'>{name}</a>, " director += f"<a href='{url}'>{name}</a>, "
director = director[:-2] director = director[:-2]
res_str += f"<b>Sutradara:</b> {director}\n" res_str += f"<b>Sutradara:</b> {director}\n"
if r_json.get("creator"): if r_json.get("creator"):
@ -595,7 +694,7 @@ async def imdb_inl(_, query):
if i["@type"] == "Person": if i["@type"] == "Person":
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
creator += f"<a href='https://www.imdb.com{url}'>{name}</a>, " creator += f"<a href='{url}'>{name}</a>, "
creator = creator[:-2] creator = creator[:-2]
res_str += f"<b>Penulis:</b> {creator}\n" res_str += f"<b>Penulis:</b> {creator}\n"
if r_json.get("actor"): if r_json.get("actor"):
@ -603,11 +702,13 @@ async def imdb_inl(_, query):
for i in r_json["actor"]: for i in r_json["actor"]:
name = i["name"] name = i["name"]
url = i["url"] url = i["url"]
actors += f"<a href='https://www.imdb.com{url}'>{name}</a>, " actors += f"<a href='{url}'>{name}</a>, "
actors = actors[:-2] actors = actors[:-2]
res_str += f"<b>Pemeran:</b> {actors}\n\n" res_str += f"<b>Pemeran:</b> {actors}\n\n"
if r_json.get("description"): if r_json.get("description"):
summary = GoogleTranslator("auto", "id").translate(r_json.get("description")) summary = GoogleTranslator("auto", "id").translate(
r_json.get("description")
)
res_str += f"<b>📜 Plot: </b> <code>{summary}</code>\n\n" res_str += f"<b>📜 Plot: </b> <code>{summary}</code>\n\n"
if r_json.get("keywords"): if r_json.get("keywords"):
keywords = r_json["keywords"].split(",") keywords = r_json["keywords"].split(",")
@ -618,7 +719,11 @@ async def imdb_inl(_, query):
key_ = key_[:-2] key_ = key_[:-2]
res_str += f"<b>🔥 Kata Kunci:</b> {key_} \n" res_str += f"<b>🔥 Kata Kunci:</b> {key_} \n"
if award := sop.select('li[data-testid="award_information"]'): if award := sop.select('li[data-testid="award_information"]'):
awards = award[0].find(class_="ipc-metadata-list-item__list-content-item").text awards = (
award[0]
.find(class_="ipc-metadata-list-item__list-content-item")
.text
)
res_str += f"<b>🏆 Penghargaan:</b> <code>{GoogleTranslator('auto', 'id').translate(awards)}</code>\n" res_str += f"<b>🏆 Penghargaan:</b> <code>{GoogleTranslator('auto', 'id').translate(awards)}</code>\n"
else: else:
res_str += "\n" res_str += "\n"
@ -632,7 +737,7 @@ async def imdb_inl(_, query):
[ [
InlineKeyboardButton( InlineKeyboardButton(
"🎬 Buka IMDB", "🎬 Buka IMDB",
url=f"https://www.imdb.com{r_json['url']}", url=url,
), ),
InlineKeyboardButton("▶️ Trailer", url=trailer_url), InlineKeyboardButton("▶️ Trailer", url=trailer_url),
] ]
@ -644,12 +749,14 @@ async def imdb_inl(_, query):
[ [
InlineKeyboardButton( InlineKeyboardButton(
"🎬 Open IMDB", "🎬 Open IMDB",
url=f"https://www.imdb.com{r_json['url']}", url=url,
) )
] ]
] ]
) )
await query.edit_message_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup) await query.edit_message_caption(
res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup
)
except (MessageNotModified, MessageIdInvalid): except (MessageNotModified, MessageIdInvalid):
pass pass
except Exception: except Exception:

View file

@ -1,7 +1,6 @@
""" """
* @author yasir <yasiramunandar@gmail.com> * @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27 * @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """

View file

@ -9,10 +9,12 @@ from pyrogram.types import (
InlineKeyboardMarkup, InlineKeyboardMarkup,
Message, Message,
) )
from misskaty.vars import COMMAND_HANDLER
from misskaty import app
from database.locale_db import set_db_lang from database.locale_db import set_db_lang
from misskaty import app
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.vars import COMMAND_HANDLER
from ..core.decorator.permissions import require_admin from ..core.decorator.permissions import require_admin
from ..helper.localization import ( from ..helper.localization import (
default_language, default_language,
@ -71,10 +73,7 @@ async def chlang(c: Client, m: Union[CallbackQuery, Message], strings):
res = strings("language_changer_private") if msg.chat.type == ChatType.PRIVATE else strings("language_changer_chat") res = strings("language_changer_private") if msg.chat.type == ChatType.PRIVATE else strings("language_changer_chat")
msg = await sender(res, reply_markup=keyboard) msg = await sender(res, reply_markup=keyboard)
try: try:
await msg.wait_for_click( await msg.wait_for_click(from_user_id=m.from_user.id, timeout=30)
from_user_id=m.from_user.id,
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_msg(strings("exp_task", context="general")) await msg.edit_msg(strings("exp_task", context="general"))

View file

@ -103,9 +103,7 @@ async def tg_lock(message, permissions: list, perm: str, lock: bool):
try: try:
await app.set_chat_permissions(message.chat.id, ChatPermissions(**permissions)) await app.set_chat_permissions(message.chat.id, ChatPermissions(**permissions))
except ChatNotModified: except ChatNotModified:
return await message.reply_text( return await message.reply_text("To unlock this, you have to unlock 'messages' first.")
"To unlock this, you have to unlock 'messages' first."
)
await message.reply_text(("Locked." if lock else "Unlocked.")) await message.reply_text(("Locked." if lock else "Unlocked."))
@ -178,7 +176,4 @@ async def url_detector(_, message):
try: try:
await message.delete_msg() await message.delete_msg()
except Exception: except Exception:
await message.reply_msg( await message.reply_msg("This message contains a URL, " + "but i don't have enough permissions to delete it")
"This message contains a URL, "
+ "but i don't have enough permissions to delete it"
)

View file

@ -12,19 +12,24 @@ from re import split as ngesplit
from time import time from time import time
from urllib.parse import unquote from urllib.parse import unquote
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message, CallbackQuery from pyrogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
Message,
)
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.helper.human_read import get_readable_time
from misskaty.helper.localization import use_chat_lang
from misskaty.helper.pyro_progress import progress_for_pyrogram from misskaty.helper.pyro_progress import progress_for_pyrogram
from misskaty.helper.tools import get_random_string from misskaty.helper.tools import get_random_string
from misskaty.helper.localization import use_chat_lang
from misskaty.helper.human_read import get_readable_time
from misskaty.plugins.dev import shell_exec from misskaty.plugins.dev import shell_exec
from misskaty.vars import COMMAND_HANDLER, FF_MPEG_NAME from misskaty.vars import COMMAND_HANDLER
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
@ -104,10 +109,7 @@ async def ceksub(self: Client, ctx: Message, strings):
strings("press_btn_msg").format(timelog=get_readable_time(timelog)), strings("press_btn_msg").format(timelog=get_readable_time(timelog)),
reply_markup=InlineKeyboardMarkup(buttons), reply_markup=InlineKeyboardMarkup(buttons),
) )
await msg.wait_for_click( await msg.wait_for_click(from_user_id=ctx.from_user.id, timeout=30)
from_user_id=ctx.from_user.id,
timeout=30
)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_msg(strings("exp_task", context="general")) await msg.edit_msg(strings("exp_task", context="general"))
except Exception: except Exception:
@ -120,12 +122,7 @@ async def ceksub(self: Client, ctx: Message, strings):
@use_chat_lang() @use_chat_lang()
async def convertsrt(self: Client, ctx: Message, strings): async def convertsrt(self: Client, ctx: Message, strings):
reply = ctx.reply_to_message reply = ctx.reply_to_message
if ( if not reply or not reply.document or not reply.document.file_name or not reply.document.file_name.endswith((".vtt", ".ass", ".srt")):
not reply
or not reply.document
or not reply.document.file_name
or not reply.document.file_name.endswith((".vtt", ".ass", ".srt"))
):
return await ctx.reply_msg(strings("conv_sub_help").format(cmd=ctx.command[0]), del_in=6) return await ctx.reply_msg(strings("conv_sub_help").format(cmd=ctx.command[0]), del_in=6)
msg = await ctx.reply_msg(strings("convert_str"), quote=True) msg = await ctx.reply_msg(strings("convert_str"), quote=True)
if not os.path.exists("downloads"): if not os.path.exists("downloads"):
@ -134,7 +131,7 @@ async def convertsrt(self: Client, ctx: Message, strings):
filename = dl.split("/", 3)[3] filename = dl.split("/", 3)[3]
LOGGER.info(f"ConvertSub: {filename} by {ctx.from_user.first_name if ctx.from_user else ctx.sender_chat.title} [{ctx.from_user.id if ctx.from_user else ctx.sender_chat.id}]") LOGGER.info(f"ConvertSub: {filename} by {ctx.from_user.first_name if ctx.from_user else ctx.sender_chat.title} [{ctx.from_user.id if ctx.from_user else ctx.sender_chat.id}]")
suffix = "srt" if ctx.command[0] == "converttosrt" else "ass" suffix = "srt" if ctx.command[0] == "converttosrt" else "ass"
(await shell_exec(f"{FF_MPEG_NAME} -i '{dl}' 'downloads/{filename}.{suffix}'"))[0] (await shell_exec(f"ffmpeg -i '{dl}' 'downloads/{filename}.{suffix}'"))[0]
c_time = time() c_time = time()
await ctx.reply_document( await ctx.reply_document(
f"downloads/{filename}.{suffix}", f"downloads/{filename}.{suffix}",
@ -177,7 +174,7 @@ async def stream_extract(self: Client, update: CallbackQuery, strings):
namafile = get_subname(lang, link, ext) namafile = get_subname(lang, link, ext)
try: try:
LOGGER.info(f"ExtractSub: {namafile} by {update.from_user.first_name} [{update.from_user.id}]") LOGGER.info(f"ExtractSub: {namafile} by {update.from_user.first_name} [{update.from_user.id}]")
(await shell_exec(f"{FF_MPEG_NAME} -i {link} -map {map} '{namafile}'"))[0] (await shell_exec(f"ffmpeg -i {link} -map {map} '{namafile}'"))[0]
timelog = time() - start_time timelog = time() - start_time
c_time = time() c_time = time()
await update.message.reply_document( await update.message.reply_document(

View file

@ -1,24 +1,24 @@
""" """
* @author yasir <yasiramunandar@gmail.com> * @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27 * @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
import io import io
import subprocess import subprocess
import time import time
from os import remove as osremove, path from os import path
from os import remove as osremove
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.file_id import FileId from pyrogram.file_id import FileId
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import progress_for_pyrogram, runcmd, post_to_telegraph from misskaty.helper import post_to_telegraph, progress_for_pyrogram, runcmd
from misskaty.helper.mediainfo_paste import mediainfo_paste
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.helper.mediainfo_paste import mediainfo_paste
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
from utils import get_file_id from utils import get_file_id
@ -54,7 +54,6 @@ JSON
DETAILS DETAILS
{out or 'Not Supported'} {out or 'Not Supported'}
""" """
file_info.message_type
try: try:
link = await mediainfo_paste(out, "MissKaty Mediainfo") link = await mediainfo_paste(out, "MissKaty Mediainfo")
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]]) markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])

View file

@ -1,16 +1,14 @@
""" """
* @author yasir <yasiramunandar@gmail.com> * @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27 * @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
import asyncio
import json import json
import os import os
import asyncio
import traceback import traceback
from PIL import Image
from logging import getLogger from logging import getLogger
from urllib.parse import quote from urllib.parse import quote
@ -18,6 +16,7 @@ import aiohttp
from bs4 import BeautifulSoup from bs4 import BeautifulSoup
from deep_translator import GoogleTranslator from deep_translator import GoogleTranslator
from gtts import gTTS from gtts import gTTS
from PIL import Image
from pyrogram import Client, filters from pyrogram import Client, filters
from pyrogram.errors import MessageTooLong, UserNotParticipant from pyrogram.errors import MessageTooLong, UserNotParticipant
from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
@ -69,7 +68,10 @@ async def readqr(c, m):
os.remove(foto) os.remove(foto)
if res := r.json()[0]["symbol"][0]["data"] is None: if res := r.json()[0]["symbol"][0]["data"] is None:
return await m.reply_msg(res) return await m.reply_msg(res)
await m.reply_msg(f"<b>QR Code Reader by @{c.me.username}:</b> <code>{r.json()[0]['symbol'][0]['data']}</code>", quote=True) await m.reply_msg(
f"<b>QR Code Reader by @{c.me.username}:</b> <code>{r.json()[0]['symbol'][0]['data']}</code>",
quote=True,
)
@app.on_message(filters.command("createqr", COMMAND_HANDLER)) @app.on_message(filters.command("createqr", COMMAND_HANDLER))
@ -80,9 +82,13 @@ async def makeqr(c, m):
elif len(m.command) > 1: elif len(m.command) > 1:
teks = m.text.split(None, 1)[1] teks = m.text.split(None, 1)[1]
else: else:
return await m.reply("Please add text after command to convert text -> QR Code.") return await m.reply(
"Please add text after command to convert text -> QR Code."
)
url = f"https://api.qrserver.com/v1/create-qr-code/?data={quote(teks)}&size=300x300" url = f"https://api.qrserver.com/v1/create-qr-code/?data={quote(teks)}&size=300x300"
await m.reply_photo(url, caption=f"<b>QR Code Maker by @{c.me.username}</b>", quote=True) await m.reply_photo(
url, caption=f"<b>QR Code Maker by @{c.me.username}</b>", quote=True
)
@app.on_message(filters.command(["sof"], COMMAND_HANDLER)) @app.on_message(filters.command(["sof"], COMMAND_HANDLER))
@ -90,13 +96,21 @@ async def makeqr(c, m):
async def stackoverflow(client, message): async def stackoverflow(client, message):
if len(message.command) == 1: if len(message.command) == 1:
return await message.reply("Give a query to search in StackOverflow!") return await message.reply("Give a query to search in StackOverflow!")
r = (await http.get(f"https://api.stackexchange.com/2.3/search/excerpts?order=asc&sort=relevance&q={message.command[1]}&accepted=True&migrated=False¬ice=False&wiki=False&site=stackoverflow")).json() r = (
await http.get(
f"https://api.stackexchange.com/2.3/search/excerpts?order=asc&sort=relevance&q={message.command[1]}&accepted=True&migrated=False¬ice=False&wiki=False&site=stackoverflow"
)
).json()
msg = await message.reply("Getting data..") msg = await message.reply("Getting data..")
hasil = "" hasil = ""
for count, data in enumerate(r["items"], start=1): for count, data in enumerate(r["items"], start=1):
question = data["question_id"] question = data["question_id"]
title = data["title"] title = data["title"]
snippet = remove_html_tags(data["excerpt"])[:80].replace("\n", "").replace(" ", "") if len(remove_html_tags(data["excerpt"])) > 80 else remove_html_tags(data["excerpt"]).replace("\n", "").replace(" ", "") snippet = (
remove_html_tags(data["excerpt"])[:80].replace("\n", "").replace(" ", "")
if len(remove_html_tags(data["excerpt"])) > 80
else remove_html_tags(data["excerpt"]).replace("\n", "").replace(" ", "")
)
hasil += f"{count}. <a href='https://stackoverflow.com/questions/{question}'>{title}</a>\n<code>{snippet}</code>\n" hasil += f"{count}. <a href='https://stackoverflow.com/questions/{question}'>{title}</a>\n<code>{snippet}</code>\n"
try: try:
await msg.edit(hasil) await msg.edit(hasil)
@ -116,7 +130,9 @@ async def gsearch(client, message):
query = message.text.split(" ", maxsplit=1)[1] query = message.text.split(" ", maxsplit=1)[1]
msg = await message.reply_text(f"**Googling** for `{query}` ...") msg = await message.reply_text(f"**Googling** for `{query}` ...")
try: try:
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edge/107.0.1418.42"} headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36 Edge/107.0.1418.42"
}
html = await http.get( html = await http.get(
f"https://www.google.com/search?q={query}&gl=id&hl=id&num=17", f"https://www.google.com/search?q={query}&gl=id&hl=id&num=17",
headers=headers, headers=headers,
@ -127,10 +143,12 @@ async def gsearch(client, message):
data = [] data = []
for result in soup.find_all("div", class_="kvH3mc BToiNc UK95Uc"): for result in soup.find_all("div", class_="kvH3mc BToiNc UK95Uc"):
link = result.find("div", class_ ="yuRUbf").find("a").get("href") link = result.find("div", class_="yuRUbf").find("a").get("href")
title = result.find("div", class_ ="yuRUbf").find("h3").get_text() title = result.find("div", class_="yuRUbf").find("h3").get_text()
try: try:
snippet = result.find("div", class_="VwiC3b yXK7lf MUxGbd yDYNvb lyLwlc lEBKkf").get_text() snippet = result.find(
"div", class_="VwiC3b yXK7lf MUxGbd yDYNvb lyLwlc lEBKkf"
).get_text()
except: except:
snippet = "-" snippet = "-"
@ -145,7 +163,9 @@ async def gsearch(client, message):
arr = json.dumps(data, indent=2, ensure_ascii=False) arr = json.dumps(data, indent=2, ensure_ascii=False)
parse = json.loads(arr) parse = json.loads(arr)
total = len(parse) total = len(parse)
res = "".join(f"<a href='{i['link']}'>{i['title']}</a>\n{i['snippet']}\n\n" for i in parse) res = "".join(
f"<a href='{i['link']}'>{i['title']}</a>\n{i['snippet']}\n\n" for i in parse
)
except Exception: except Exception:
exc = traceback.format_exc() exc = traceback.format_exc()
return await msg.edit(exc) return await msg.edit(exc)
@ -159,7 +179,9 @@ async def gsearch(client, message):
@capture_err @capture_err
@ratelimiter @ratelimiter
async def translate(client, message): async def translate(client, message):
if message.reply_to_message and (message.reply_to_message.text or message.reply_to_message.caption): if message.reply_to_message and (
message.reply_to_message.text or message.reply_to_message.caption
):
target_lang = "id" if len(message.command) == 1 else message.text.split()[1] target_lang = "id" if len(message.command) == 1 else message.text.split()[1]
text = message.reply_to_message.text or message.reply_to_message.caption text = message.reply_to_message.text or message.reply_to_message.caption
else: else:
@ -173,10 +195,14 @@ async def translate(client, message):
try: try:
my_translator = GoogleTranslator(source="auto", target=target_lang) my_translator = GoogleTranslator(source="auto", target=target_lang)
result = my_translator.translate(text=text) result = my_translator.translate(text=text)
await msg.edit_msg(f"Translation using source = {my_translator.source} and target = {my_translator.target}\n\n-> {result}") await msg.edit_msg(
f"Translation using source = {my_translator.source} and target = {my_translator.target}\n\n-> {result}"
)
except MessageTooLong: except MessageTooLong:
url = await rentry(result) url = await rentry(result)
await msg.edit_msg(f"Your translated text pasted to rentry because has long text:\n{url}") await msg.edit_msg(
f"Your translated text pasted to rentry because has long text:\n{url}"
)
except Exception as err: except Exception as err:
await msg.edit_msg(f"Oppss, Error: <code>{str(err)}</code>") await msg.edit_msg(f"Oppss, Error: <code>{str(err)}</code>")
@ -185,7 +211,9 @@ async def translate(client, message):
@capture_err @capture_err
@ratelimiter @ratelimiter
async def tts(_, message): async def tts(_, message):
if message.reply_to_message and (message.reply_to_message.text or message.reply_to_message.caption): if message.reply_to_message and (
message.reply_to_message.text or message.reply_to_message.caption
):
if len(message.text.split()) == 1: if len(message.text.split()) == 1:
target_lang = "id" target_lang = "id"
else: else:
@ -239,12 +267,21 @@ async def topho(client, message):
if not message.reply_to_message or not message.reply_to_message.sticker: if not message.reply_to_message or not message.reply_to_message.sticker:
return await message.reply_text("Reply ke sticker untuk mengubah ke foto") return await message.reply_text("Reply ke sticker untuk mengubah ke foto")
if message.reply_to_message.sticker.is_animated: if message.reply_to_message.sticker.is_animated:
return await message.reply_text("Ini sticker animasi, command ini hanya untuk sticker biasa.") return await message.reply_text(
"Ini sticker animasi, command ini hanya untuk sticker biasa."
)
photo = await message.reply_to_message.download() photo = await message.reply_to_message.download()
im = Image.open(photo).convert("RGB") im = Image.open(photo).convert("RGB")
filename = f"toimg_{message.from_user.id}.png" filename = f"toimg_{message.from_user.id}.png"
im.save(filename, "png") im.save(filename, "png")
await asyncio.gather(*[message.reply_document(filename), message.reply_photo(filename, caption=f"Sticker -> Image\n@{client.me.username}")]) await asyncio.gather(
*[
message.reply_document(filename),
message.reply_photo(
filename, caption=f"Sticker -> Image\n@{client.me.username}"
),
]
)
os.remove(photo) os.remove(photo)
os.remove(filename) os.remove(filename)
except Exception as e: except Exception as e:
@ -278,10 +315,16 @@ async def showid(client, message):
) )
file_info = get_file_id(message.reply_to_message) file_info = get_file_id(message.reply_to_message)
else: else:
_id += "<b>➲ User ID</b>: " f"<code>{message.from_user.id if message.from_user else 'Anonymous'}</code>\n" _id += (
"<b>➲ User ID</b>: "
f"<code>{message.from_user.id if message.from_user else 'Anonymous'}</code>\n"
)
file_info = get_file_id(message) file_info = get_file_id(message)
if file_info: if file_info:
_id += f"<b>{file_info.message_type}</b>: " f"<code>{file_info.file_id}</code>\n" _id += (
f"<b>{file_info.message_type}</b>: "
f"<code>{file_info.file_id}</code>\n"
)
await message.reply_text(_id, quote=True) await message.reply_text(_id, quote=True)
@ -316,12 +359,20 @@ async def who_is(client, message):
try: try:
chat_member_p = await message.chat.get_member(from_user.id) chat_member_p = await message.chat.get_member(from_user.id)
joined_date = chat_member_p.joined_date joined_date = chat_member_p.joined_date
message_out_str += "<b>➲Joined this Chat on:</b> <code>" f"{joined_date}" "</code>\n" message_out_str += (
"<b>➲Joined this Chat on:</b> <code>" f"{joined_date}" "</code>\n"
)
except UserNotParticipant: except UserNotParticipant:
pass pass
if chat_photo := from_user.photo: if chat_photo := from_user.photo:
local_user_photo = await client.download_media(message=chat_photo.big_file_id) local_user_photo = await client.download_media(message=chat_photo.big_file_id)
buttons = [[InlineKeyboardButton("🔐 Close", callback_data=f"close#{message.from_user.id}")]] buttons = [
[
InlineKeyboardButton(
"🔐 Close", callback_data=f"close#{message.from_user.id}"
)
]
]
reply_markup = InlineKeyboardMarkup(buttons) reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_photo( await message.reply_photo(
photo=local_user_photo, photo=local_user_photo,
@ -332,7 +383,13 @@ async def who_is(client, message):
) )
os.remove(local_user_photo) os.remove(local_user_photo)
else: else:
buttons = [[InlineKeyboardButton("🔐 Close", callback_data=f"close#{message.from_user.id}")]] buttons = [
[
InlineKeyboardButton(
"🔐 Close", callback_data=f"close#{message.from_user.id}"
)
]
]
reply_markup = InlineKeyboardMarkup(buttons) reply_markup = InlineKeyboardMarkup(buttons)
await message.reply_text( await message.reply_text(
text=message_out_str, text=message_out_str,
@ -358,7 +415,9 @@ async def close_callback(bot: Client, query: CallbackQuery):
pass pass
headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10"} headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/600.1.17 (KHTML, like Gecko) Version/7.1 Safari/537.85.10"
}
async def get_content(url): async def get_content(url):
@ -369,9 +428,8 @@ async def get_content(url):
async def mdlapi(title): async def mdlapi(title):
link = f"https://kuryana.vercel.app/search/q/{title}" link = f"https://kuryana.vercel.app/search/q/{title}"
async with aiohttp.ClientSession() as ses: async with aiohttp.ClientSession() as ses, ses.get(link) as result:
async with ses.get(link) as result: return await result.json()
return await result.json()
@app.on_message(filters.command(["mdl"], COMMAND_HANDLER)) @app.on_message(filters.command(["mdl"], COMMAND_HANDLER))
@ -412,16 +470,22 @@ async def mdl_callback(bot: Client, query: CallbackQuery):
try: try:
res = (await http.get(f"https://kuryana.vercel.app/id/{slug}")).json() res = (await http.get(f"https://kuryana.vercel.app/id/{slug}")).json()
result += f"<b>Title:</b> <a href='{res['data']['link']}'>{res['data']['title']}</a>\n" result += f"<b>Title:</b> <a href='{res['data']['link']}'>{res['data']['title']}</a>\n"
result += f"<b>AKA:</b> <code>{res['data']['others']['also_known_as']}</code>\n\n" result += (
f"<b>AKA:</b> <code>{res['data']['others']['also_known_as']}</code>\n\n"
)
result += f"<b>Rating:</b> <code>{res['data']['details']['score']}</code>\n" result += f"<b>Rating:</b> <code>{res['data']['details']['score']}</code>\n"
result += f"<b>Content Rating:</b> <code>{res['data']['details']['content_rating']}</code>\n" result += f"<b>Content Rating:</b> <code>{res['data']['details']['content_rating']}</code>\n"
result += f"<b>Type:</b> <code>{res['data']['details']['type']}</code>\n" result += f"<b>Type:</b> <code>{res['data']['details']['type']}</code>\n"
result += f"<b>Country:</b> <code>{res['data']['details']['country']}</code>\n" result += (
f"<b>Country:</b> <code>{res['data']['details']['country']}</code>\n"
)
if res["data"]["details"]["type"] == "Movie": if res["data"]["details"]["type"] == "Movie":
result += f"<b>Release Date:</b> <code>{res['data']['details']['release_date']}</code>\n" result += f"<b>Release Date:</b> <code>{res['data']['details']['release_date']}</code>\n"
elif res["data"]["details"]["type"] == "Drama": elif res["data"]["details"]["type"] == "Drama":
result += f"<b>Episode:</b> {res['data']['details']['episodes']}\n" result += f"<b>Episode:</b> {res['data']['details']['episodes']}\n"
result += f"<b>Aired:</b> <code>{res['data']['details']['aired']}</code>\n" result += (
f"<b>Aired:</b> <code>{res['data']['details']['aired']}</code>\n"
)
try: try:
result += f"<b>Aired on:</b> <code>{res['data']['details']['aired_on']}</code>\n" result += f"<b>Aired on:</b> <code>{res['data']['details']['aired_on']}</code>\n"
except: except:
@ -430,11 +494,17 @@ async def mdl_callback(bot: Client, query: CallbackQuery):
result += f"<b>Original Network:</b> <code>{res['data']['details']['original_network']}</code>\n" result += f"<b>Original Network:</b> <code>{res['data']['details']['original_network']}</code>\n"
except: except:
pass pass
result += f"<b>Duration:</b> <code>{res['data']['details']['duration']}</code>\n" result += (
result += f"<b>Genre:</b> <code>{res['data']['others']['genres']}</code>\n\n" f"<b>Duration:</b> <code>{res['data']['details']['duration']}</code>\n"
)
result += (
f"<b>Genre:</b> <code>{res['data']['others']['genres']}</code>\n\n"
)
result += f"<b>Synopsis:</b> <code>{res['data']['synopsis']}</code>\n" result += f"<b>Synopsis:</b> <code>{res['data']['synopsis']}</code>\n"
result += f"<b>Tags:</b> <code>{res['data']['others']['tags']}</code>\n" result += f"<b>Tags:</b> <code>{res['data']['others']['tags']}</code>\n"
btn = InlineKeyboardMarkup([[InlineKeyboardButton("🎬 Open MyDramaList", url=res["data"]["link"])]]) btn = InlineKeyboardMarkup(
[[InlineKeyboardButton("🎬 Open MyDramaList", url=res["data"]["link"])]]
)
await query.message.edit_text(result, reply_markup=btn) await query.message.edit_text(result, reply_markup=btn)
except Exception as e: except Exception as e:
await query.message.edit_text(f"<b>ERROR:</b>\n<code>{e}</code>") await query.message.edit_text(f"<b>ERROR:</b>\n<code>{e}</code>")

View file

@ -1,18 +1,27 @@
import re # * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import platform import platform
import re
from datetime import datetime, timedelta from datetime import datetime, timedelta
import pytz import pytz
from apscheduler.jobstores.base import ConflictingIdError from apscheduler.jobstores.base import ConflictingIdError
from pyrogram import filters, __version__ from pyrogram import __version__, filters
from pyrogram.errors import ChannelInvalid, ChannelPrivate, ChatAdminRequired, ChatNotModified from pyrogram.errors import (
ChannelInvalid,
ChannelPrivate,
ChatAdminRequired,
ChatNotModified,
)
from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup
from database.locale_db import get_db_lang from database.locale_db import get_db_lang
from misskaty import BOT_NAME, app, scheduler from misskaty import BOT_NAME, app, scheduler
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import require_admin from misskaty.core.decorator.permissions import require_admin
from misskaty.helper.localization import use_chat_lang, langdict from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.localization import langdict, use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, TZ from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, TZ
__MODULE__ = "NightMode" __MODULE__ = "NightMode"
@ -92,19 +101,32 @@ async def un_mute_chat(chat_id: int, perm: ChatPermissions):
try: try:
await app.set_chat_permissions(chat_id, perm) await app.set_chat_permissions(chat_id, perm)
except ChatAdminRequired: except ChatAdminRequired:
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_not_admin"].format(chat_id=chat_id, bname=BOT_NAME)) await app.send_message(
LOG_CHANNEL,
langdict[getlang]["nightmodev2"]["nmd_off_not_admin"].format(chat_id=chat_id, bname=BOT_NAME),
)
except (ChannelInvalid, ChannelPrivate): except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}") scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_nightmode_{chat_id}") scheduler.remove_job(f"disable_nightmode_{chat_id}")
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_not_present"].format(chat_id=chat_id, bname=BOT_NAME)) await app.send_message(
LOG_CHANNEL,
langdict[getlang]["nightmodev2"]["nmd_off_not_present"].format(chat_id=chat_id, bname=BOT_NAME),
)
except ChatNotModified: except ChatNotModified:
pass pass
except Exception as e: except Exception as e:
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_err"].format(chat_id=chat_id, e=e)) await app.send_message(
LOG_CHANNEL,
langdict[getlang]["nightmodev2"]["nmd_off_err"].format(chat_id=chat_id, e=e),
)
else: else:
job = scheduler.get_job(f"enable_nightmode_{chat_id}") job = scheduler.get_job(f"enable_nightmode_{chat_id}")
close_at = job.next_run_time close_at = job.next_run_time
await app.send_message(chat_id, langdict[getlang]["nightmodev2"]["nmd_off_success"].format(dt=tglsekarang(), close_at=close_at), reply_markup=reply_markup) await app.send_message(
chat_id,
langdict[getlang]["nightmodev2"]["nmd_off_success"].format(dt=tglsekarang(), close_at=close_at),
reply_markup=reply_markup,
)
async def mute_chat(chat_id: int): async def mute_chat(chat_id: int):
@ -113,19 +135,32 @@ async def mute_chat(chat_id: int):
try: try:
await app.set_chat_permissions(chat_id, ChatPermissions()) await app.set_chat_permissions(chat_id, ChatPermissions())
except ChatAdminRequired: except ChatAdminRequired:
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_not_admin"].format(chat_id=chat_id, bname=BOT_NAME)) await app.send_message(
LOG_CHANNEL,
langdict[getlang]["nightmodev2"]["nmd_on_not_admin"].format(chat_id=chat_id, bname=BOT_NAME),
)
except (ChannelInvalid, ChannelPrivate): except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}") scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_nightmode_{chat_id}") scheduler.remove_job(f"disable_nightmode_{chat_id}")
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_not_present"].format(chat_id=chat_id, bname=BOT_NAME)) await app.send_message(
LOG_CHANNEL,
langdict[getlang]["nightmodev2"]["nmd_on_not_present"].format(chat_id=chat_id, bname=BOT_NAME),
)
except ChatNotModified: except ChatNotModified:
pass pass
except Exception as e: except Exception as e:
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_err"].format(chat_id=chat_id, e=e)) await app.send_message(
LOG_CHANNEL,
langdict[getlang]["nightmodev2"]["nmd_on_err"].format(chat_id=chat_id, e=e),
)
else: else:
job = scheduler.get_job(f"disable_nightmode_{chat_id}") job = scheduler.get_job(f"disable_nightmode_{chat_id}")
open_at = job.next_run_time open_at = job.next_run_time
await app.send_message(chat_id, langdict[getlang]["nightmodev2"]["nmd_on_success"].format(dt=tglsekarang(), open_at=open_at), reply_markup=reply_markup) await app.send_message(
chat_id,
langdict[getlang]["nightmodev2"]["nmd_on_success"].format(dt=tglsekarang(), open_at=open_at),
reply_markup=reply_markup,
)
@app.on_message(filters.command("nightmode", COMMAND_HANDLER) & filters.group) @app.on_message(filters.command("nightmode", COMMAND_HANDLER) & filters.group)
@ -163,10 +198,28 @@ async def nightmode_handler(c, msg, strings):
end_time_stamp = start_timestamp + timedelta(seconds=int(lock_dur)) end_time_stamp = start_timestamp + timedelta(seconds=int(lock_dur))
try: try:
# schedule to enable nightmode # schedule to enable nightmode
scheduler.add_job(mute_chat, "interval", [chat_id], id=f"enable_nightmode_{chat_id}", days=1, next_run_time=start_timestamp, max_instances=50, misfire_grace_time=None) scheduler.add_job(
mute_chat,
"interval",
[chat_id],
id=f"enable_nightmode_{chat_id}",
days=1,
next_run_time=start_timestamp,
max_instances=50,
misfire_grace_time=None,
)
# schedule to disable nightmode # schedule to disable nightmode
scheduler.add_job(un_mute_chat, "interval", [chat_id, msg.chat.permissions], id=f"disable_nightmode_{chat_id}", days=1, next_run_time=end_time_stamp, max_instances=50, misfire_grace_time=None) scheduler.add_job(
un_mute_chat,
"interval",
[chat_id, msg.chat.permissions],
id=f"disable_nightmode_{chat_id}",
days=1,
next_run_time=end_time_stamp,
max_instances=50,
misfire_grace_time=None,
)
except ConflictingIdError: except ConflictingIdError:
return await msg.reply_msg(strings("schedule_already_on")) return await msg.reply_msg(strings("schedule_already_on"))
await msg.reply_msg(strings("nmd_enable_success").format(st=start_timestamp.strftime("%H:%M:%S"), lockdur=lockdur)) await msg.reply_msg(strings("nmd_enable_success").format(st=start_timestamp.strftime("%H:%M:%S"), lockdur=lockdur))
@ -178,4 +231,7 @@ async def nightmode_handler(c, msg, strings):
@ratelimiter @ratelimiter
@use_chat_lang() @use_chat_lang()
async def callbackanightmd(c, q, strings): async def callbackanightmd(c, q, strings):
await q.answer(strings("nmd_cb").format(bname=c.me.first_name, ver=__version__, pyver=platform.python_version()), show_alert=True) await q.answer(
strings("nmd_cb").format(bname=c.me.first_name, ver=__version__, pyver=platform.python_version()),
show_alert=True,
)

View file

@ -28,8 +28,8 @@ from pyrogram import filters
from database.notes_db import delete_note, get_note, get_note_names, save_note from database.notes_db import delete_note, get_note, get_note_names, save_note
from misskaty import app from misskaty import app
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import adminsOnly from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb from misskaty.core.keyboard import ikb
from misskaty.helper.functions import extract_text_and_keyb from misskaty.helper.functions import extract_text_and_keyb
@ -64,7 +64,6 @@ async def save_notee(_, message):
"type": _type, "type": _type,
"data": message.reply_to_message.text.markdown if _type == "text" else message.reply_to_message.sticker.file_id, "data": message.reply_to_message.text.markdown if _type == "text" else message.reply_to_message.sticker.file_id,
} }
message.text.split()[0][0]
chat_id = message.chat.id chat_id = message.chat.id
await save_note(chat_id, name, note) await save_note(chat_id, name, note)
await message.reply(f"__**Saved note {name}.**__") await message.reply(f"__**Saved note {name}.**__")
@ -74,7 +73,6 @@ async def save_notee(_, message):
@capture_err @capture_err
@ratelimiter @ratelimiter
async def get_notes(_, message): async def get_notes(_, message):
message.text.split()[0][0]
chat_id = message.chat.id chat_id = message.chat.id
_notes = await get_note_names(chat_id) _notes = await get_note_names(chat_id)
@ -123,7 +121,6 @@ async def del_note(_, message):
if not name: if not name:
return await message.reply("**Usage**\n__/delnote [NOTE_NAME]__") return await message.reply("**Usage**\n__/delnote [NOTE_NAME]__")
message.text.split()[0][0]
chat_id = message.chat.id chat_id = message.chat.id
deleted = await delete_note(chat_id, name) deleted = await delete_note(chat_id, name)

View file

@ -1,15 +1,22 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import os import os
from PIL import Image, ImageDraw, ImageFont
from pyrogram import filters
from misskaty import app from misskaty import app
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
from PIL import Image, ImageFont, ImageDraw
from pyrogram import filters
__MODULE__ = "nulis" __MODULE__ = "nulis"
__HELP__ = """ __HELP__ = """
Command: <code>/nulis</code> [reply to msg or after cmd] Command: <code>/nulis</code> [reply to msg or after cmd]
Desc: For those of you who are lazy to write. Desc: For those of you who are lazy to write.
""" """
def text_set(text): def text_set(text):
lines = [] lines = []
if len(text) <= 55: if len(text) <= 55:
@ -24,6 +31,7 @@ def text_set(text):
lines.extend(line[((z - 1) * 55) : (z * 55)] for z in range(1, k + 2)) lines.extend(line[((z - 1) * 55) : (z * 55)] for z in range(1, k + 2))
return lines[:25] return lines[:25]
@app.on_message(filters.command(["nulis"], COMMAND_HANDLER)) @app.on_message(filters.command(["nulis"], COMMAND_HANDLER))
async def handwrite(client, message): async def handwrite(client, message):
if message.reply_to_message and message.reply_to_message.text: if message.reply_to_message and message.reply_to_message.text:
@ -46,9 +54,7 @@ async def handwrite(client, message):
file = f"nulis_{message.from_user.id}.jpg" file = f"nulis_{message.from_user.id}.jpg"
img.save(file) img.save(file)
if os.path.exists(file): if os.path.exists(file):
await message.reply_photo( await message.reply_photo(photo=file, caption=f"<b>Written By :</b> {client.me.mention}")
photo=file, caption=f"<b>Written By :</b> {client.me.mention}"
)
os.remove(file) os.remove(file)
await nan.delete() await nan.delete()
except Exception as e: except Exception as e:

View file

@ -1,7 +1,6 @@
""" """
* @author yasir <yasiramunandar@gmail.com> * @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27 * @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
@ -9,15 +8,15 @@
import os import os
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message from pyrogram.types import Message
from telegraph.aio import Telegraph from telegraph.aio import Telegraph
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.helper.localization import use_chat_lang from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "OCR" __MODULE__ = "OCR"
@ -30,15 +29,7 @@ __HELP__ = "/ocr [reply to photo] - Read Text From Image"
@use_chat_lang() @use_chat_lang()
async def ocr(self: Client, ctx: Message, strings): async def ocr(self: Client, ctx: Message, strings):
reply = ctx.reply_to_message reply = ctx.reply_to_message
if ( if not reply or not reply.sticker and not reply.photo and (not reply.document or not reply.document.mime_type.startswith("image")):
not reply
or not reply.sticker
and not reply.photo
and (
not reply.document
or not reply.document.mime_type.startswith("image")
)
):
return await ctx.reply_msg(strings("no_photo").format(cmd=ctx.command[0]), quote=True) return await ctx.reply_msg(strings("no_photo").format(cmd=ctx.command[0]), quote=True)
msg = await ctx.reply_msg(strings("read_ocr"), quote=True) msg = await ctx.reply_msg(strings("read_ocr"), quote=True)
try: try:
@ -59,4 +50,4 @@ async def ocr(self: Client, ctx: Message, strings):
except Exception as e: except Exception as e:
await msg.edit_msg(str(e)) await msg.edit_msg(str(e))
if os.path.exists(file_path): if os.path.exists(file_path):
os.remove(file_path) os.remove(file_path)

View file

@ -13,7 +13,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import http, rentry, post_to_telegraph from misskaty.helper import http, post_to_telegraph, rentry
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "Paste" __MODULE__ = "Paste"
@ -32,7 +32,7 @@ def humanbytes(size: int):
"""Convert Bytes To Bytes So That Human Can Read It""" """Convert Bytes To Bytes So That Human Can Read It"""
if not isinstance(size, int): if not isinstance(size, int):
try: try:
size = size pass
except ValueError: except ValueError:
size = None size = None
if not size: if not size:
@ -70,7 +70,10 @@ pattern = compiles(r"^text/|json$|yaml$|xml$|toml$|x-sh$|x-shellscript$|x-subrip
async def telegraph_paste(_, message): async def telegraph_paste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg(f"**Reply To A Message With /{message.command[0]} or with command**", del_in=6) return await message.reply_msg(
f"**Reply To A Message With /{message.command[0]} or with command**",
del_in=6,
)
if message.from_user: if message.from_user:
if message.from_user.username: if message.from_user.username:
@ -89,21 +92,35 @@ async def telegraph_paste(_, message):
return msg.edit_msg(f"Failed to upload. ERR: {err}") return msg.edit_msg(f"Failed to upload. ERR: {err}")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully upload your media to Telegraph<a href='{url}'>.</a>\n\nUpload by {uname}**" pasted = f"**Successfully upload your media to Telegraph<a href='{url}'>.</a>\n\nUpload by {uname}**"
remove(file) remove(file)
return await msg.edit_msg(pasted, disable_web_page_preview=True, reply_markup=InlineKeyboardMarkup(button)) return await msg.edit_msg(
pasted,
disable_web_page_preview=True,
reply_markup=InlineKeyboardMarkup(button),
)
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg(f"**You can only paste files smaller than {humanbytes(limit)}.**") return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**"
)
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
title = message.text.split(None, 1)[1] if len(message.command) > 1 else "MissKaty Paste" title = (
message.text.split(None, 1)[1]
if len(message.command) > 1
else "MissKaty Paste"
)
try: try:
with open(file, "r") as text: with open(file, "r") as text:
data = text.read() data = text.read()
@ -115,8 +132,14 @@ async def telegraph_paste(_, message):
pass pass
return await msg.edit_msg("`File Not Supported !`") return await msg.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption): elif reply and (reply.text or reply.caption):
title = message.text.split(None, 1)[1] if len(message.command) > 1 else "MissKaty Paste" title = (
data = reply.text.html.replace("\n", "<br>") or reply.caption.html.replace("\n", "<br>") message.text.split(None, 1)[1]
if len(message.command) > 1
else "MissKaty Paste"
)
data = reply.text.html.replace("\n", "<br>") or reply.caption.html.replace(
"\n", "<br>"
)
elif not reply and len(message.command) >= 2: elif not reply and len(message.command) >= 2:
title = "MissKaty Paste" title = "MissKaty Paste"
data = message.text.split(None, 1)[1] data = message.text.split(None, 1)[1]
@ -130,7 +153,11 @@ async def telegraph_paste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully pasted your data to Telegraph<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Telegraph<a href='{url}'>.</a>\n\nPaste by {uname}**"
@ -144,14 +171,18 @@ async def wastepaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg(f"**Reply To A Message With /{target} or with command**", del_in=6) return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6
)
msg = await message.reply_msg("`Pasting to YasirBin...`") msg = await message.reply_msg("`Pasting to YasirBin...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg(f"**You can only paste files smaller than {humanbytes(limit)}.**") return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**"
)
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
@ -195,7 +226,11 @@ async def wastepaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully pasted your data to YasirBin<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to YasirBin<a href='{url}'>.</a>\n\nPaste by {uname}**"
@ -209,14 +244,18 @@ async def nekopaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg(f"**Reply To A Message With /{target} or with command**", del_in=6) return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6
)
msg = await message.reply_msg("`Pasting to Nekobin...`") msg = await message.reply_msg("`Pasting to Nekobin...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await message.edit_msg(f"**You can only paste files smaller than {humanbytes(limit)}.**") return await message.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**"
)
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await message.edit_msg("**Only text files can be pasted.**") return await message.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
@ -239,12 +278,16 @@ async def nekopaste(_, message):
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
)
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
try: try:
x = (await http.post("https://nekobin.com/api/documents", json={"content": data})).json() x = (
await http.post("https://nekobin.com/api/documents", json={"content": data})
).json()
url = f"https://nekobin.com/{x['result']['key']}" url = f"https://nekobin.com/{x['result']['key']}"
except Exception as e: except Exception as e:
return await msg.edit_msg(f"ERROR: {e}") return await msg.edit_msg(f"ERROR: {e}")
@ -253,7 +296,11 @@ async def nekopaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully pasted your data to Nekobin<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Nekobin<a href='{url}'>.</a>\n\nPaste by {uname}**"
@ -267,14 +314,18 @@ async def spacebinn(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg(f"**Reply To A Message With /{target} or with command**", del_in=6) return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6
)
msg = await message.reply_msg("`Pasting to Spacebin...`") msg = await message.reply_msg("`Pasting to Spacebin...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg(f"**You can only paste files smaller than {humanbytes(limit)}.**") return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**"
)
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
@ -297,7 +348,9 @@ async def spacebinn(_, message):
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
)
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
@ -313,7 +366,11 @@ async def spacebinn(_, message):
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully pasted your data to Spacebin<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Spacebin<a href='{url}'>.</a>\n\nPaste by {uname}**"
@ -327,14 +384,18 @@ async def rentrypaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.reply_msg(f"**Reply To A Message With /{target} or with command**", del_in=6) return await message.reply_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6
)
msg = await message.reply_msg("`Pasting to Rentry...`") msg = await message.reply_msg("`Pasting to Rentry...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg(f"**You can only paste files smaller than {humanbytes(limit)}.**") return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**"
)
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
@ -357,7 +418,9 @@ async def rentrypaste(_, message):
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
)
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
@ -370,7 +433,11 @@ async def rentrypaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully pasted your data to Rentry<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Rentry<a href='{url}'>.</a>\n\nPaste by {uname}**"
@ -384,14 +451,18 @@ async def tempaste(_, message):
reply = message.reply_to_message reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0] target = str(message.command[0]).split("@", maxsplit=1)[0]
if not reply and len(message.command) < 2: if not reply and len(message.command) < 2:
return await message.edit_msg(f"**Reply To A Message With /{target} or with command**", del_in=6) return await message.edit_msg(
f"**Reply To A Message With /{target} or with command**", del_in=6
)
msg = await message.reply_msg("`Pasting to TempPaste...`") msg = await message.reply_msg("`Pasting to TempPaste...`")
data = "" data = ""
limit = 1024 * 1024 limit = 1024 * 1024
if reply and reply.document: if reply and reply.document:
if reply.document.file_size > limit: if reply.document.file_size > limit:
return await msg.edit_msg(f"**You can only paste files smaller than {humanbytes(limit)}.**") return await msg.edit_msg(
f"**You can only paste files smaller than {humanbytes(limit)}.**"
)
if not pattern.search(reply.document.mime_type): if not pattern.search(reply.document.mime_type):
return await msg.edit_msg("**Only text files can be pasted.**") return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download() file = await reply.download()
@ -414,7 +485,9 @@ async def tempaste(_, message):
if message.from_user.username: if message.from_user.username:
uname = f"@{message.from_user.username}" uname = f"@{message.from_user.username}"
else: else:
uname = f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})" uname = (
f"[{message.from_user.first_name}](tg://user?id={message.from_user.id})"
)
else: else:
uname = message.sender_chat.title uname = message.sender_chat.title
@ -438,7 +511,11 @@ async def tempaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems") return await msg.edit_msg("Text Too Short Or File Problems")
button = [ button = [
[InlineKeyboardButton("Open Link", url=url)], [InlineKeyboardButton("Open Link", url=url)],
[InlineKeyboardButton("Share Link", url=f"https://telegram.me/share/url?url={url}")], [
InlineKeyboardButton(
"Share Link", url=f"https://telegram.me/share/url?url={url}"
)
],
] ]
pasted = f"**Successfully pasted your data to Tempaste<a href='{url}'>.</a>\n\nPaste by {uname}**" pasted = f"**Successfully pasted your data to Tempaste<a href='{url}'>.</a>\n\nPaste by {uname}**"

View file

@ -4,20 +4,20 @@
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
import time
import os
import platform import platform
import time
from asyncio import Lock from asyncio import Lock
from re import MULTILINE, findall from re import MULTILINE, findall
from subprocess import run as srun from subprocess import run as srun
from pyrogram import filters, Client, __version__ as pyrover from pyrogram import Client
from pyrogram import __version__ as pyrover
from pyrogram import filters
from pyrogram.types import Message from pyrogram.types import Message
from misskaty import app, botStartTime, misskaty_version from misskaty import app, botStartTime, misskaty_version
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.human_read import get_readable_time from misskaty.helper.human_read import get_readable_time
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
@ -29,7 +29,9 @@ async def ping(self: Client, ctx: Message):
rm = await ctx.reply_msg("🐱 Pong!!...") rm = await ctx.reply_msg("🐱 Pong!!...")
end_t = time.time() end_t = time.time()
time_taken_s = round(end_t - start_t, 3) time_taken_s = round(end_t - start_t, 3)
await rm.edit_msg(f"<b>🐈 MissKatyBot {misskaty_version} based Pyrogram {pyrover} Online.</b>\n\n<b>Ping:</b> <code>{time_taken_s} detik</code>\n<b>Uptime:</b> <code>{currentTime}</code>\n<b>Python Version:</b> <code>{platform.python_version()}</code>") await rm.edit_msg(
f"<b>🐈 MissKatyBot {misskaty_version} based Pyrogram {pyrover} Online.</b>\n\n<b>Ping:</b> <code>{time_taken_s} detik</code>\n<b>Uptime:</b> <code>{currentTime}</code>\n<b>Python Version:</b> <code>{platform.python_version()}</code>"
)
@app.on_message(filters.command(["ping_dc"], COMMAND_HANDLER)) @app.on_message(filters.command(["ping_dc"], COMMAND_HANDLER))

View file

@ -1,18 +1,17 @@
""" """
* @author yasir <yasiramunandar@gmail.com> * @author yasir <yasiramunandar@gmail.com>
* @date 2023-01-23 19:41:27 * @date 2023-01-23 19:41:27
* @lastModified 2023-01-23 19:41:31
* @projectName MissKatyPyro * @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
from pykeyboard import InlineButton, InlineKeyboard from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message, CallbackQuery from pyrogram.types import CallbackQuery, Message
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.plugins.web_scraper import split_arr, headers from misskaty.plugins.web_scraper import headers, split_arr
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
PYPI_DICT = {} PYPI_DICT = {}
@ -77,7 +76,11 @@ async def pypipage_callback(self: Client, callback_query: CallbackQuery):
return return
keyboard = InlineKeyboard() keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_pypi#{number}" + f"#{message_id}#{callback_query.from_user.id}") keyboard.paginate(
PageLen,
CurrentPage,
"page_pypi#{number}" + f"#{message_id}#{callback_query.from_user.id}",
)
keyboard.row(InlineButton("👇 Extract Data ", "Hmmm")) keyboard.row(InlineButton("👇 Extract Data ", "Hmmm"))
keyboard.row(*btn) keyboard.row(*btn)
keyboard.row(InlineButton("❌ Close", f"close#{callback_query.from_user.id}")) keyboard.row(InlineButton("❌ Close", f"close#{callback_query.from_user.id}"))
@ -98,7 +101,13 @@ async def pypi_getdata(self: Client, callback_query: CallbackQuery):
return await callback_query.answer("Invalid callback data, please send CMD again..") return await callback_query.answer("Invalid callback data, please send CMD again..")
keyboard = InlineKeyboard() keyboard = InlineKeyboard()
keyboard.row(InlineButton("↩️ Back", f"page_pypi#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton("❌ Close", f"close#{callback_query.from_user.id}")) keyboard.row(
InlineButton(
"↩️ Back",
f"page_pypi#{CurrentPage}#{message_id}#{callback_query.from_user.id}",
),
InlineButton("❌ Close", f"close#{callback_query.from_user.id}"),
)
try: try:
html = await http.get(f"https://pypi.org/pypi/{pkgname}/json", headers=headers) html = await http.get(f"https://pypi.org/pypi/{pkgname}/json", headers=headers)
res = html.json() res = html.json()

View file

@ -1,11 +1,15 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
from io import BytesIO from io import BytesIO
from pyrogram import Client, filters from pyrogram import Client, filters
from pyrogram.types import Message from pyrogram.types import Message
from misskaty import app from misskaty import app
from misskaty.helper.http import http
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
__MODULE__ = "Fun" __MODULE__ = "Fun"
__HELP__ = """ __HELP__ = """

View file

@ -1,3 +1,7 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
from pyrogram import Client, filters from pyrogram import Client, filters
from pyrogram.types import Message from pyrogram.types import Message
@ -25,7 +29,12 @@ async def cek_mataa(self: Client, ctx: Message, strings):
if ctx.sender_chat or not await is_sangmata_on(ctx.chat.id): if ctx.sender_chat or not await is_sangmata_on(ctx.chat.id):
return return
if not await cek_userdata(ctx.from_user.id): if not await cek_userdata(ctx.from_user.id):
return await add_userdata(ctx.from_user.id, ctx.from_user.username, ctx.from_user.first_name, ctx.from_user.last_name) return await add_userdata(
ctx.from_user.id,
ctx.from_user.username,
ctx.from_user.first_name,
ctx.from_user.last_name,
)
usernamebefore, first_name, lastname_before = await get_userdata(ctx.from_user.id) usernamebefore, first_name, lastname_before = await get_userdata(ctx.from_user.id)
msg = "" msg = ""
if usernamebefore != ctx.from_user.username or first_name != ctx.from_user.first_name or lastname_before != ctx.from_user.last_name: if usernamebefore != ctx.from_user.username or first_name != ctx.from_user.first_name or lastname_before != ctx.from_user.last_name:
@ -34,15 +43,30 @@ async def cek_mataa(self: Client, ctx: Message, strings):
usernamebefore = f"@{usernamebefore}" if usernamebefore else strings("no_uname") usernamebefore = f"@{usernamebefore}" if usernamebefore else strings("no_uname")
usernameafter = f"@{ctx.from_user.username}" if ctx.from_user.username else strings("no_uname") usernameafter = f"@{ctx.from_user.username}" if ctx.from_user.username else strings("no_uname")
msg += strings("uname_change_msg").format(bef=usernamebefore, aft=usernameafter) msg += strings("uname_change_msg").format(bef=usernamebefore, aft=usernameafter)
await add_userdata(ctx.from_user.id, ctx.from_user.username, ctx.from_user.first_name, ctx.from_user.last_name) await add_userdata(
ctx.from_user.id,
ctx.from_user.username,
ctx.from_user.first_name,
ctx.from_user.last_name,
)
if first_name != ctx.from_user.first_name: if first_name != ctx.from_user.first_name:
msg += strings("firstname_change_msg").format(bef=first_name, aft=ctx.from_user.first_name) msg += strings("firstname_change_msg").format(bef=first_name, aft=ctx.from_user.first_name)
await add_userdata(ctx.from_user.id, ctx.from_user.username, ctx.from_user.first_name, ctx.from_user.last_name) await add_userdata(
ctx.from_user.id,
ctx.from_user.username,
ctx.from_user.first_name,
ctx.from_user.last_name,
)
if lastname_before != ctx.from_user.last_name: if lastname_before != ctx.from_user.last_name:
lastname_before = lastname_before or strings("no_last_name") lastname_before = lastname_before or strings("no_last_name")
lastname_after = ctx.from_user.last_name or strings("no_last_name") lastname_after = ctx.from_user.last_name or strings("no_last_name")
msg += strings("lastname_change_msg").format(bef=lastname_before, aft=lastname_after) msg += strings("lastname_change_msg").format(bef=lastname_before, aft=lastname_after)
await add_userdata(ctx.from_user.id, ctx.from_user.username, ctx.from_user.first_name, ctx.from_user.last_name) await add_userdata(
ctx.from_user.id,
ctx.from_user.username,
ctx.from_user.first_name,
ctx.from_user.last_name,
)
if msg != "": if msg != "":
await ctx.reply_msg(msg, quote=True) await ctx.reply_msg(msg, quote=True)

View file

@ -4,9 +4,9 @@
import html import html
import regex import regex
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message
from pyrogram.errors import MessageEmpty from pyrogram.errors import MessageEmpty
from pyrogram.types import Message
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter

View file

@ -2,15 +2,29 @@ import traceback
from logging import getLogger from logging import getLogger
from pyrogram import Client, filters from pyrogram import Client, filters
from pyrogram.errors import ApiIdInvalid, PasswordHashInvalid, PhoneCodeExpired, PhoneCodeInvalid, PhoneNumberInvalid, SessionPasswordNeeded from pyrogram.errors import (
ApiIdInvalid,
PasswordHashInvalid,
PhoneCodeExpired,
PhoneCodeInvalid,
PhoneNumberInvalid,
SessionPasswordNeeded,
)
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from telethon import TelegramClient from telethon import TelegramClient
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout from telethon.errors import (
from telethon.errors import ApiIdInvalidError, PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError, PhoneNumberInvalidError, SessionPasswordNeededError ApiIdInvalidError,
PasswordHashInvalidError,
PhoneCodeExpiredError,
PhoneCodeInvalidError,
PhoneNumberInvalidError,
SessionPasswordNeededError,
)
from telethon.sessions import StringSession from telethon.sessions import StringSession
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.vars import API_HASH, API_ID, COMMAND_HANDLER from misskaty.vars import API_HASH, API_ID, COMMAND_HANDLER
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
@ -38,12 +52,19 @@ gen_button = [[InlineKeyboardButton(text="🙄 Generate Session 🙄", callback_
async def is_batal(msg): async def is_batal(msg):
if msg.text == "/cancel": if msg.text == "/cancel":
await msg.reply("**» Cancelled the ongoing string session generation process !**", quote=True, reply_markup=InlineKeyboardMarkup(gen_button)) await msg.reply(
"**» Cancelled the ongoing string session generation process !**",
quote=True,
reply_markup=InlineKeyboardMarkup(gen_button),
)
return True return True
elif msg.text == "/skip": elif msg.text == "/skip":
return False return False
elif msg.text.startswith("/"): # Bot Commands elif msg.text.startswith("/"): # Bot Commands
await msg.reply("**» Cancelled the ongoing string session generation process !**", quote=True) await msg.reply(
"**» Cancelled the ongoing string session generation process !**",
quote=True,
)
return True return True
else: else:
return False return False
@ -87,8 +108,10 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
if is_bot: if is_bot:
ty += " Bot" ty += " Bot"
await msg.reply(f"» Trying to start **{ty}** session generator...") await msg.reply(f"» Trying to start **{ty}** session generator...")
msg.chat.id api_id_msg = await msg.chat.ask(
api_id_msg = await msg.chat.ask("Please send your **API_ID** to proceed.\n\nClick on /skip for using bot's api.", filters=filters.text) "Please send your **API_ID** to proceed.\n\nClick on /skip for using bot's api.",
filters=filters.text,
)
if await is_batal(api_id_msg): if await is_batal(api_id_msg):
return return
if api_id_msg.text == "/skip": if api_id_msg.text == "/skip":
@ -99,7 +122,11 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
api_id = int(api_id_msg.text) api_id = int(api_id_msg.text)
await api_id_msg.delete() await api_id_msg.delete()
except ValueError: except ValueError:
return await api_id_msg.reply("**API_ID** must be integer, start generating your session again.", quote=True, reply_markup=InlineKeyboardMarkup(gen_button)) return await api_id_msg.reply(
"**API_ID** must be integer, start generating your session again.",
quote=True,
reply_markup=InlineKeyboardMarkup(gen_button),
)
api_hash_msg = await msg.chat.ask("» Now please send your **API_HASH** to continue.", filters=filters.text) api_hash_msg = await msg.chat.ask("» Now please send your **API_HASH** to continue.", filters=filters.text)
if await is_batal(api_hash_msg): if await is_batal(api_hash_msg):
return return
@ -118,7 +145,13 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
if telethon and is_bot or telethon: if telethon and is_bot or telethon:
client = TelegramClient(StringSession(), api_id, api_hash) client = TelegramClient(StringSession(), api_id, api_hash)
elif is_bot: elif is_bot:
client = Client(name="bot", api_id=api_id, api_hash=api_hash, bot_token=phone_number, in_memory=True) client = Client(
name="bot",
api_id=api_id,
api_hash=api_hash,
bot_token=phone_number,
in_memory=True,
)
else: else:
client = Client(name="user", api_id=api_id, api_hash=api_hash, in_memory=True) client = Client(name="user", api_id=api_id, api_hash=api_hash, in_memory=True)
await client.connect() await client.connect()
@ -130,17 +163,30 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
else: else:
code = await client.send_code(phone_number) code = await client.send_code(phone_number)
except (ApiIdInvalid, ApiIdInvalidError): except (ApiIdInvalid, ApiIdInvalidError):
return await msg.reply("» Your **API_ID** and **API_HASH** combination doesn't match. \n\nPlease start generating your session again.", reply_markup=InlineKeyboardMarkup(gen_button)) return await msg.reply(
"» Your **API_ID** and **API_HASH** combination doesn't match. \n\nPlease start generating your session again.",
reply_markup=InlineKeyboardMarkup(gen_button),
)
except (PhoneNumberInvalid, PhoneNumberInvalidError): except (PhoneNumberInvalid, PhoneNumberInvalidError):
return await msg.reply("» The **PHONE_NUMBER** you've doesn't belong to any account in Telegram.\n\nPlease start generating your session again.", reply_markup=InlineKeyboardMarkup(gen_button)) return await msg.reply(
"» The **PHONE_NUMBER** you've doesn't belong to any account in Telegram.\n\nPlease start generating your session again.",
reply_markup=InlineKeyboardMarkup(gen_button),
)
try: try:
phone_code_msg = None phone_code_msg = None
if not is_bot: if not is_bot:
phone_code_msg = await msg.chat.ask("» Please send the **OTP** That you've received from Telegram on your account.\nIf OTP is `12345`, **please send it as** `1 2 3 4 5`.", filters=filters.text, timeout=600) phone_code_msg = await msg.chat.ask(
"» Please send the **OTP** That you've received from Telegram on your account.\nIf OTP is `12345`, **please send it as** `1 2 3 4 5`.",
filters=filters.text,
timeout=600,
)
if await is_batal(phone_code_msg): if await is_batal(phone_code_msg):
return return
except ListenerTimeout: except ListenerTimeout:
return await msg.reply("» Time limit reached of 10 minutes.\n\nPlease start generating your session again.", reply_markup=InlineKeyboardMarkup(gen_button)) return await msg.reply(
"» Time limit reached of 10 minutes.\n\nPlease start generating your session again.",
reply_markup=InlineKeyboardMarkup(gen_button),
)
if not is_bot: if not is_bot:
phone_code = phone_code_msg.text.replace(" ", "") phone_code = phone_code_msg.text.replace(" ", "")
await phone_code_msg.delete() await phone_code_msg.delete()
@ -150,14 +196,27 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
else: else:
await client.sign_in(phone_number, code.phone_code_hash, phone_code) await client.sign_in(phone_number, code.phone_code_hash, phone_code)
except (PhoneCodeInvalid, PhoneCodeInvalidError): except (PhoneCodeInvalid, PhoneCodeInvalidError):
return await msg.reply("» The OTP you've sent is **wrong.**\n\nPlease start generating your session again.", reply_markup=InlineKeyboardMarkup(gen_button)) return await msg.reply(
"» The OTP you've sent is **wrong.**\n\nPlease start generating your session again.",
reply_markup=InlineKeyboardMarkup(gen_button),
)
except (PhoneCodeExpired, PhoneCodeExpiredError): except (PhoneCodeExpired, PhoneCodeExpiredError):
return await msg.reply("» The OTP you've sent is **expired.**\n\nPlease start generating your session again.", reply_markup=InlineKeyboardMarkup(gen_button)) return await msg.reply(
"» The OTP you've sent is **expired.**\n\nPlease start generating your session again.",
reply_markup=InlineKeyboardMarkup(gen_button),
)
except (SessionPasswordNeeded, SessionPasswordNeededError): except (SessionPasswordNeeded, SessionPasswordNeededError):
try: try:
two_step_msg = await msg.chat.ask("» Please enter your **Two Step Verification** password to continue.", filters=filters.text, timeout=300) two_step_msg = await msg.chat.ask(
"» Please enter your **Two Step Verification** password to continue.",
filters=filters.text,
timeout=300,
)
except ListenerTimeout: except ListenerTimeout:
return await msg.reply("» Time limit reached of 5 minutes.\n\nPlease start generating your session again.", reply_markup=InlineKeyboardMarkup(gen_button)) return await msg.reply(
"» Time limit reached of 5 minutes.\n\nPlease start generating your session again.",
reply_markup=InlineKeyboardMarkup(gen_button),
)
try: try:
password = two_step_msg.text password = two_step_msg.text
await two_step_msg.delete() await two_step_msg.delete()
@ -168,7 +227,11 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
if await is_batal(api_id_msg): if await is_batal(api_id_msg):
return return
except (PasswordHashInvalid, PasswordHashInvalidError): except (PasswordHashInvalid, PasswordHashInvalidError):
return await two_step_msg.reply("» The password you've sent is wrong.\n\nPlease start generating session again.", quote=True, reply_markup=InlineKeyboardMarkup(gen_button)) return await two_step_msg.reply(
"» The password you've sent is wrong.\n\nPlease start generating session again.",
quote=True,
reply_markup=InlineKeyboardMarkup(gen_button),
)
elif telethon: elif telethon:
await client.start(bot_token=phone_number) await client.start(bot_token=phone_number)
else: else:

View file

@ -6,16 +6,20 @@
* Copyright @YasirPedia All rights reserved * Copyright @YasirPedia All rights reserved
""" """
import re import re
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message, CallbackQuery
from database.users_chats_db import db from pyrogram import Client, filters
from pyrogram import filters, Client from pyrogram.types import (
from pyrogram.errors import ChannelPrivate CallbackQuery,
from misskaty import app, BOT_USERNAME, HELPABLE, BOT_NAME InlineKeyboardButton,
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL InlineKeyboardMarkup,
Message,
)
from misskaty import BOT_NAME, BOT_USERNAME, HELPABLE, app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import bot_sys_stats, paginate_modules from misskaty.helper import bot_sys_stats, paginate_modules
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
home_keyboard_pm = InlineKeyboardMarkup( home_keyboard_pm = InlineKeyboardMarkup(
[ [
@ -68,35 +72,20 @@ keyboard = InlineKeyboardMarkup(
@use_chat_lang() @use_chat_lang()
async def start(self: Client, ctx: Message, strings): async def start(self: Client, ctx: Message, strings):
if ctx.chat.type.value != "private": if ctx.chat.type.value != "private":
if not await db.get_chat(ctx.chat.id):
try:
total = await app.get_chat_members_count(ctx.chat.id)
except ChannelPrivate:
return await ctx.chat.leave()
await app.send_message(
LOG_CHANNEL,
strings("newgroup_log").format(jdl=ctx.chat.title, id=ctx.chat.id, c=total),
)
await db.add_chat(ctx.chat.id, ctx.chat.title)
nama = ctx.from_user.mention if ctx.from_user else ctx.sender_chat.title nama = ctx.from_user.mention if ctx.from_user else ctx.sender_chat.title
return await ctx.reply_photo( return await ctx.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg", photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=strings("start_msg").format(kamuh=nama), caption=strings("start_msg").format(kamuh=nama),
reply_markup=keyboard, reply_markup=keyboard,
) )
if not await db.is_user_exist(ctx.from_user.id):
await db.add_user(ctx.from_user.id, ctx.from_user.first_name)
await app.send_message(
LOG_CHANNEL,
strings("newuser_log").format(id=ctx.from_user.id, nm=ctx.from_user.mention),
)
if len(ctx.text.split()) > 1: if len(ctx.text.split()) > 1:
name = (ctx.text.split(None, 1)[1]).lower() name = (ctx.text.split(None, 1)[1]).lower()
if "_" in name: if "_" in name:
module = name.split("_", 1)[1] module = name.split("_", 1)[1]
text = strings("help_name").format(mod=HELPABLE[module].__MODULE__) + HELPABLE[module].__HELP__ text = (
strings("help_name").format(mod=HELPABLE[module].__MODULE__)
+ HELPABLE[module].__HELP__
)
await ctx.reply_msg(text, disable_web_page_preview=True) await ctx.reply_msg(text, disable_web_page_preview=True)
elif name == "help": elif name == "help":
text, keyb = await help_parser(ctx.from_user.first_name) text, keyb = await help_parser(ctx.from_user.first_name)
@ -136,14 +125,6 @@ async def stats_callbacc(self: Client, cb: CallbackQuery):
@use_chat_lang() @use_chat_lang()
async def help_command(self: Client, ctx: Message, strings): async def help_command(self: Client, ctx: Message, strings):
if ctx.chat.type.value != "private": if ctx.chat.type.value != "private":
if not await db.get_chat(ctx.chat.id):
total = await app.get_chat_members_count(ctx.chat.id)
await app.send_message(
LOG_CHANNEL,
strings("newgroup_log").format(jdl=ctx.chat.title, id=ctx.chat.id, c=total),
)
await db.add_chat(ctx.chat.id, ctx.chat.title)
if len(ctx.command) >= 2: if len(ctx.command) >= 2:
name = (ctx.text.split(None, 1)[1]).replace(" ", "_").lower() name = (ctx.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE: if str(name) in HELPABLE:
@ -165,29 +146,26 @@ async def help_command(self: Client, ctx: Message, strings):
await ctx.reply_msg(strings("pm_detail"), reply_markup=keyboard) await ctx.reply_msg(strings("pm_detail"), reply_markup=keyboard)
else: else:
await ctx.reply_msg(strings("pm_detail"), reply_markup=keyboard) await ctx.reply_msg(strings("pm_detail"), reply_markup=keyboard)
else: elif len(ctx.command) >= 2:
if not await db.is_user_exist(ctx.from_user.id): name = (ctx.text.split(None, 1)[1]).replace(" ", "_").lower()
await db.add_user(ctx.from_user.id, ctx.from_user.first_name) if str(name) in HELPABLE:
await app.send_message( text = (
LOG_CHANNEL, strings("help_name").format(mod=HELPABLE[name].__MODULE__)
strings("newuser_log").format(id=ctx.from_user.id, nm=ctx.from_user.mention), + HELPABLE[name].__HELP__
) )
await ctx.reply_msg(text, disable_web_page_preview=True)
if len(ctx.command) >= 2:
name = (ctx.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE:
text = strings("help_name").format(mod=HELPABLE[name].__MODULE__) + HELPABLE[name].__HELP__
await ctx.reply_msg(text, disable_web_page_preview=True)
else:
text, help_keyboard = await help_parser(ctx.from_user.first_name)
await ctx.reply_msg(
text,
reply_markup=help_keyboard,
disable_web_page_preview=True,
)
else: else:
text, help_keyboard = await help_parser(ctx.from_user.first_name) text, help_keyboard = await help_parser(ctx.from_user.first_name)
await ctx.reply_msg(text, reply_markup=help_keyboard, disable_web_page_preview=True) await ctx.reply_msg(
text,
reply_markup=help_keyboard,
disable_web_page_preview=True,
)
else:
text, help_keyboard = await help_parser(ctx.from_user.first_name)
await ctx.reply_msg(
text, reply_markup=help_keyboard, disable_web_page_preview=True
)
async def help_parser(name, keyboard=None): async def help_parser(name, keyboard=None):
@ -217,14 +195,21 @@ async def help_button(self: Client, query: CallbackQuery, strings):
next_match = re.match(r"help_next\((.+?)\)", query.data) next_match = re.match(r"help_next\((.+?)\)", query.data)
back_match = re.match(r"help_back", query.data) back_match = re.match(r"help_back", query.data)
create_match = re.match(r"help_create", query.data) create_match = re.match(r"help_create", query.data)
top_text = strings("help_txt").format(kamuh=query.from_user.first_name, bot=self.me.first_name) top_text = strings("help_txt").format(
kamuh=query.from_user.first_name, bot=self.me.first_name
)
if mod_match: if mod_match:
module = mod_match[1].replace(" ", "_") module = mod_match[1].replace(" ", "_")
text = strings("help_name").format(mod=HELPABLE[module].__MODULE__) + HELPABLE[module].__HELP__ text = (
strings("help_name").format(mod=HELPABLE[module].__MODULE__)
+ HELPABLE[module].__HELP__
)
await query.message.edit_msg( await query.message.edit_msg(
text=text, text=text,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(strings("back_btn"), callback_data="help_back")]]), reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton(strings("back_btn"), callback_data="help_back")]]
),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
elif home_match: elif home_match:
@ -238,7 +223,9 @@ async def help_button(self: Client, query: CallbackQuery, strings):
curr_page = int(prev_match[1]) curr_page = int(prev_match[1])
await query.message.edit_msg( await query.message.edit_msg(
text=top_text, text=top_text,
reply_markup=InlineKeyboardMarkup(paginate_modules(curr_page - 1, HELPABLE, "help")), reply_markup=InlineKeyboardMarkup(
paginate_modules(curr_page - 1, HELPABLE, "help")
),
disable_web_page_preview=True, disable_web_page_preview=True,
) )
@ -246,7 +233,9 @@ async def help_button(self: Client, query: CallbackQuery, strings):
next_page = int(next_match[1]) next_page = int(next_match[1])
await query.message.edit_msg( await query.message.edit_msg(
text=top_text, text=top_text,
reply_markup=InlineKeyboardMarkup(paginate_modules(next_page + 1, HELPABLE, "help")), reply_markup=InlineKeyboardMarkup(
paginate_modules(next_page + 1, HELPABLE, "help")
),
disable_web_page_preview=True, disable_web_page_preview=True,
) )

View file

@ -1,3 +1,7 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import asyncio import asyncio
import os import os
import re import re
@ -5,19 +9,29 @@ import shutil
import tempfile import tempfile
from PIL import Image from PIL import Image
from pyrogram import emoji, filters, enums, Client from pyrogram import Client, emoji, enums, filters
from pyrogram.errors import BadRequest, PeerIdInvalid, StickersetInvalid from pyrogram.errors import BadRequest, PeerIdInvalid, StickersetInvalid
from pyrogram.file_id import FileId from pyrogram.file_id import FileId
from pyrogram.raw.functions.messages import GetStickerSet, SendMedia from pyrogram.raw.functions.messages import GetStickerSet, SendMedia
from pyrogram.raw.functions.stickers import AddStickerToSet, CreateStickerSet, RemoveStickerFromSet from pyrogram.raw.functions.stickers import (
from pyrogram.raw.types import DocumentAttributeFilename, InputDocument, InputMediaUploadedDocument, InputStickerSetItem, InputStickerSetShortName AddStickerToSet,
CreateStickerSet,
RemoveStickerFromSet,
)
from pyrogram.raw.types import (
DocumentAttributeFilename,
InputDocument,
InputMediaUploadedDocument,
InputStickerSetItem,
InputStickerSetShortName,
)
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from misskaty import BOT_USERNAME, app from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, FF_MPEG_NAME from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
__MODULE__ = "Stickers" __MODULE__ = "Stickers"
__HELP__ = """ __HELP__ = """
@ -76,7 +90,7 @@ async def getstickerid(self: Client, ctx: Message):
@app.on_message(filters.command("unkang", COMMAND_HANDLER) & filters.reply) @app.on_message(filters.command("unkang", COMMAND_HANDLER) & filters.reply)
@ratelimiter @ratelimiter
@use_chat_lang() @use_chat_lang()
async def getstickerid(self: Client, ctx: Message, strings): async def unkangs(self: Client, ctx: Message, strings):
if not ctx.from_user: if not ctx.from_user:
return await ctx.reply("You're anon, unkang in my PM") return await ctx.reply("You're anon, unkang in my PM")
if sticker := ctx.reply_to_message.sticker: if sticker := ctx.reply_to_message.sticker:
@ -339,7 +353,7 @@ async def convert_video(filename: str) -> str:
downpath, f_name = os.path.split(filename) downpath, f_name = os.path.split(filename)
webm_video = os.path.join(downpath, f"{f_name.split('.', 1)[0]}.webm") webm_video = os.path.join(downpath, f"{f_name.split('.', 1)[0]}.webm")
cmd = [ cmd = [
FF_MPEG_NAME, "ffmpeg",
"-loglevel", "-loglevel",
"quiet", "quiet",
"-i", "-i",

View file

@ -1,3 +1,7 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import asyncio import asyncio
import logging import logging
import os import os
@ -108,7 +112,11 @@ async def subsceneCMD(self: Client, ctx: Message):
if not subres: if not subres:
return return
keyboard = InlineKeyboard() keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "subscenepage#{number}" + f"#{pesan.id}#{ctx.from_user.id}") keyboard.paginate(
PageLen,
CurrentPage,
"subscenepage#{number}" + f"#{pesan.id}#{ctx.from_user.id}",
)
keyboard.row(InlineButton("👇 Extract Data ", "Hmmm")) keyboard.row(InlineButton("👇 Extract Data ", "Hmmm"))
keyboard.row(*btn1) keyboard.row(*btn1)
if btn2: if btn2:
@ -138,7 +146,11 @@ async def subpage_callback(self: Client, callback_query: CallbackQuery):
return return
keyboard = InlineKeyboard() keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "subscenepage#{number}" + f"#{message_id}#{callback_query.from_user.id}") keyboard.paginate(
PageLen,
CurrentPage,
"subscenepage#{number}" + f"#{message_id}#{callback_query.from_user.id}",
)
keyboard.row(InlineButton("👇 Get Subtitle List", "Hmmm")) keyboard.row(InlineButton("👇 Get Subtitle List", "Hmmm"))
keyboard.row(*btn1) keyboard.row(*btn1)
if btn2: if btn2:
@ -169,7 +181,11 @@ async def subdlpage_callback(self: Client, callback_query: CallbackQuery):
return return
keyboard = InlineKeyboard() keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "sublist#{number}" + f"#{idlink}#{message_id}#{callback_query.from_user.id}") keyboard.paginate(
PageLen,
CurrentPage,
"sublist#{number}" + f"#{idlink}#{message_id}#{callback_query.from_user.id}",
)
keyboard.row(InlineButton("👇 Download Subtitle", "Hmmm")) keyboard.row(InlineButton("👇 Download Subtitle", "Hmmm"))
keyboard.row(*btn1) keyboard.row(*btn1)
if btn2: if btn2:
@ -198,5 +214,8 @@ async def dlsub_callback(self: Client, callback_query: CallbackQuery):
res = await down_page(link) res = await down_page(link)
dl = scraper.get(res.get("download_url")) dl = scraper.get(res.get("download_url"))
f = open(f"{title}.zip", mode="wb").write(dl.content) f = open(f"{title}.zip", mode="wb").write(dl.content)
await callback_query.message.reply_document(f"{title}.zip", caption=f"Title: {res.get('title')}\nIMDb: {res['imdb']}\nAuthor: {res['author_name']}\nRelease Info: ") await callback_query.message.reply_document(
f"{title}.zip",
caption=f"Title: {res.get('title')}\nIMDb: {res['imdb']}\nAuthor: {res['author_name']}\nRelease Info: ",
)
os.remove(f"{title}.zip") os.remove(f"{title}.zip")

View file

@ -1,5 +1,5 @@
# This plugin to learn session using pyrogram # This plugin to learn session using pyrogram
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message from pyrogram.types import Message
from misskaty import app from misskaty import app

View file

@ -1,6 +1,6 @@
from pykeyboard import InlineKeyboard from pykeyboard import InlineKeyboard
from pyrogram import Client, filters from pyrogram import Client, filters
from pyrogram.types import Message, CallbackQuery from pyrogram.types import CallbackQuery, Message
from misskaty import app from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
@ -9,19 +9,36 @@ from misskaty.vars import COMMAND_HANDLER
async def getData(chat_id, message_id, GetWord, CurrentPage): async def getData(chat_id, message_id, GetWord, CurrentPage):
UDJson = (await http.get(f"https://api.urbandictionary.com/v0/define?term={GetWord}")).json() UDJson = (
await http.get(f"https://api.urbandictionary.com/v0/define?term={GetWord}")
).json()
if "list" not in UDJson: if "list" not in UDJson:
return await app.send_msg(chat_id=chat_id, reply_to_message_id=message_id, text=f"Word: {GetWord}\nResults: Sorry could not find any matching results!", del_in=5) return await app.send_msg(
chat_id=chat_id,
reply_to_message_id=message_id,
text=f"Word: {GetWord}\nResults: Sorry could not find any matching results!",
del_in=5,
)
try: try:
index = int(CurrentPage - 1) index = int(CurrentPage - 1)
PageLen = len(UDJson["list"]) PageLen = len(UDJson["list"])
UDReasult = f"**Definition of {GetWord}**\n" f"{UDJson['list'][index]['definition']}\n\n" "**📌 Examples**\n" f"__{UDJson['list'][index]['example']}__" UDReasult = (
f"**Definition of {GetWord}**\n"
f"{UDJson['list'][index]['definition']}\n\n"
"**📌 Examples**\n"
f"__{UDJson['list'][index]['example']}__"
)
UDFReasult = "".join(i for i in UDReasult if i not in "[]") UDFReasult = "".join(i for i in UDReasult if i not in "[]")
return (UDFReasult, PageLen) return (UDFReasult, PageLen)
except IndexError or KeyError: except (IndexError, KeyError):
await app.send_msg(chat_id=chat_id, reply_to_message_id=message_id, text=f"Word: {GetWord}\nResults: Sorry could not find any matching results!", del_in=5) await app.send_msg(
chat_id=chat_id,
reply_to_message_id=message_id,
text=f"Word: {GetWord}\nResults: Sorry could not find any matching results!",
del_in=5,
)
@app.on_message(filters.command(["ud"], COMMAND_HANDLER)) @app.on_message(filters.command(["ud"], COMMAND_HANDLER))
@ -45,7 +62,9 @@ async def urbanDictionary(self: Client, ctx: Message):
await ctx.reply_msg(text=f"{UDReasult}", reply_markup=keyboard) await ctx.reply_msg(text=f"{UDReasult}", reply_markup=keyboard)
@app.on_callback_query(filters.create(lambda _, __, query: "pagination_urban#" in query.data)) @app.on_callback_query(
filters.create(lambda _, __, query: "pagination_urban#" in query.data)
)
@ratelimiter @ratelimiter
async def ud_callback(self: Client, callback_query: CallbackQuery): async def ud_callback(self: Client, callback_query: CallbackQuery):
message_id = callback_query.message.id message_id = callback_query.message.id

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,11 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import os import os
from asyncio import gather from asyncio import gather
from pyrogram import filters, Client from pyrogram import Client, filters
from pyrogram.types import Message from pyrogram.types import Message
from pySmartDL import SmartDL from pySmartDL import SmartDL
@ -31,7 +35,12 @@ async def take_ss(self: Client, ctx: Message, strings):
url = f"https://webss.yasirapi.eu.org/api?url={url}&width=1280&height=720" url = f"https://webss.yasirapi.eu.org/api?url={url}&width=1280&height=720"
downloader = SmartDL(url, download_file_path, progress_bar=False, timeout=10) downloader = SmartDL(url, download_file_path, progress_bar=False, timeout=10)
downloader.start(blocking=True) downloader.start(blocking=True)
await gather(*[ctx.reply_document(download_file_path), ctx.reply_photo(download_file_path, caption=strings("str_credit"))]) await gather(
*[
ctx.reply_document(download_file_path),
ctx.reply_photo(download_file_path, caption=strings("str_credit")),
]
)
await msg.delete_msg() await msg.delete_msg()
os.remove(download_file_path) os.remove(download_file_path)
except Exception as e: except Exception as e:

View file

@ -1,23 +1,33 @@
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
from logging import getLogger from logging import getLogger
from re import compile as recompile
from uuid import uuid4 from uuid import uuid4
from iytdl import iYTDL, main, Process from iytdl import Process, iYTDL, main
from iytdl.exceptions import DownloadFailedError
from iytdl.constants import YT_VID_URL from iytdl.constants import YT_VID_URL
from pyrogram import filters, Client from iytdl.exceptions import DownloadFailedError
from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message from pyrogram import Client, filters
from pyrogram.errors import MessageIdInvalid
from pyrogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
InputMediaPhoto,
Message,
)
from misskaty import app from misskaty import app
from misskaty.core.decorator.errors import capture_err from misskaty.core.decorator.errors import capture_err
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.helper.localization import use_chat_lang from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, FF_MPEG_NAME from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
YT_REGEX = "^(https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?(?P<id>[A-Za-z0-9\-=_]{11})" YT_REGEX = r"^(https?://)?(www\.)?(youtube|youtu|youtube-nocookie)\.(com|be)/(watch\?v=|embed/|v/|.+\?v=)?(?P<id>[A-Za-z0-9\-=_]{11})"
YT_DB = {} YT_DB = {}
@ -42,7 +52,13 @@ async def ytsearch(self: Client, ctx: Message, strings):
return await ctx.reply_msg(strings("no_res").format(kweri=query)) return await ctx.reply_msg(strings("no_res").format(kweri=query))
i = search["result"][0] i = search["result"][0]
out = f"<b><a href={i['link']}>{i['title']}</a></b>\n" out = f"<b><a href={i['link']}>{i['title']}</a></b>\n"
out = strings("yts_msg").format(pub=i["publishedTime"], dur=i["duration"], vi=i["viewCount"]["short"], clink=i["channel"]["link"], cname=i["channel"]["name"]) out = strings("yts_msg").format(
pub=i["publishedTime"],
dur=i["duration"],
vi=i["viewCount"]["short"],
clink=i["channel"]["link"],
cname=i["channel"]["name"],
)
btn = InlineKeyboardMarkup( btn = InlineKeyboardMarkup(
[ [
[ [
@ -51,7 +67,11 @@ async def ytsearch(self: Client, ctx: Message, strings):
callback_data=f"ytdl_scroll|{search_key}|1", callback_data=f"ytdl_scroll|{search_key}|1",
) )
], ],
[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")], [
InlineKeyboardButton(
strings("dl_btn"), callback_data=f"yt_gen|{i['id']}"
)
],
] ]
) )
img = await get_ytthumb(i["id"]) img = await get_ytthumb(i["id"])
@ -60,7 +80,10 @@ async def ytsearch(self: Client, ctx: Message, strings):
await ctx.reply_photo(img, caption=caption, reply_markup=markup, quote=True) await ctx.reply_photo(img, caption=caption, reply_markup=markup, quote=True)
@app.on_message(filters.command(["ytdown"], COMMAND_HANDLER) | filters.regex(YT_REGEX) & ~filters.channel) @app.on_message(
filters.command(["ytdown"], COMMAND_HANDLER)
| filters.regex(YT_REGEX) & ~filters.channel
)
@capture_err @capture_err
@ratelimiter @ratelimiter
@use_chat_lang() @use_chat_lang()
@ -70,7 +93,9 @@ async def ytdownv2(self: Client, ctx: Message, strings):
if ctx.command and len(ctx.command) == 1: if ctx.command and len(ctx.command) == 1:
return await ctx.reply_msg(strings("invalid_link")) return await ctx.reply_msg(strings("invalid_link"))
url = ctx.input if ctx.command and len(ctx.command) > 1 else ctx.text url = ctx.input if ctx.command and len(ctx.command) > 1 else ctx.text
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location=f"/usr/bin/{FF_MPEG_NAME}") as ytdl: async with iYTDL(
log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/ffmpeg"
) as ytdl:
try: try:
x = await ytdl.parse(url, extract=True) x = await ytdl.parse(url, extract=True)
if x is None: if x is None:
@ -78,11 +103,10 @@ async def ytdownv2(self: Client, ctx: Message, strings):
caption = x.caption caption = x.caption
markup = x.buttons markup = x.buttons
photo = x.image_url photo = x.image_url
msg = await ctx.reply_photo(photo, caption=caption, reply_markup=markup, quote=True) msg = await ctx.reply_photo(
await msg.wait_for_click( photo, caption=caption, reply_markup=markup, quote=True
from_user_id=ctx.from_user.id,
timeout=30
) )
await msg.wait_for_click(from_user_id=ctx.from_user.id, timeout=30)
except ListenerTimeout: except ListenerTimeout:
await msg.edit_caption(strings("exp_task", context="general")) await msg.edit_caption(strings("exp_task", context="general"))
except Exception as err: except Exception as err:
@ -96,9 +120,13 @@ async def ytdl_listall_callback(self: Client, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id: if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer(strings("unauth"), True) return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|") callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location=f"/usr/bin/{FF_MPEG_NAME}") as ytdl: async with iYTDL(
log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/ffmpeg"
) as ytdl:
media, buttons = await ytdl.listview(callback[1]) media, buttons = await ytdl.listview(callback[1])
await cq.edit_message_media(media=media, reply_markup=buttons.add(cq.from_user.id)) await cq.edit_message_media(
media=media, reply_markup=buttons.add(cq.from_user.id)
)
@app.on_callback_query(filters.regex(r"^yt_extract_info")) @app.on_callback_query(filters.regex(r"^yt_extract_info"))
@ -109,7 +137,9 @@ async def ytdl_extractinfo_callback(self: Client, cq: CallbackQuery, strings):
return await cq.answer(strings("unauth"), True) return await cq.answer(strings("unauth"), True)
await cq.answer(strings("wait")) await cq.answer(strings("wait"))
callback = cq.data.split("|") callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location=f"/usr/bin/{FF_MPEG_NAME}") as ytdl: async with iYTDL(
log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/ffmpeg"
) as ytdl:
try: try:
if data := await ytdl.extract_info_from_key(callback[1]): if data := await ytdl.extract_info_from_key(callback[1]):
if len(callback[1]) == 11: if len(callback[1]) == 11:
@ -142,7 +172,7 @@ async def ytdl_gendl_callback(self: Client, cq: CallbackQuery, strings):
async with iYTDL( async with iYTDL(
log_group_id=LOG_CHANNEL, log_group_id=LOG_CHANNEL,
cache_path="cache", cache_path="cache",
ffmpeg_location=f"/usr/bin/{FF_MPEG_NAME}", ffmpeg_location="/usr/bin/ffmpeg",
delete_media=True, delete_media=True,
) as ytdl: ) as ytdl:
try: try:
@ -170,7 +200,12 @@ async def ytdl_gendl_callback(self: Client, cq: CallbackQuery, strings):
except DownloadFailedError as e: except DownloadFailedError as e:
await cq.edit_message_caption(f"Download Failed - {e}") await cq.edit_message_caption(f"Download Failed - {e}")
except Exception as err: except Exception as err:
await cq.edit_message_caption(f"Download Failed for url -> {video_link}\n\n<b>ERROR:</b> <code>{err}</code>") try:
await cq.edit_message_caption(
f"Download Failed for url -> {video_link}\n\n<b>ERROR:</b> <code>{err}</code>"
)
except MessageIdInvalid:
pass
@app.on_callback_query(filters.regex(r"^yt_cancel")) @app.on_callback_query(filters.regex(r"^yt_cancel"))
@ -202,10 +237,18 @@ async def ytdl_scroll_callback(self: Client, cq: CallbackQuery, strings):
search = await main.VideosSearch(query).next() search = await main.VideosSearch(query).next()
i = search["result"][page] i = search["result"][page]
out = f"<b><a href={i['link']}>{i['title']}</a></b>" out = f"<b><a href={i['link']}>{i['title']}</a></b>"
out = strings("yts_msg").format(pub=i["publishedTime"], dur=i["duration"], vi=i["viewCount"]["short"], clink=i["channel"]["link"], cname=i["channel"]["name"]) out = strings("yts_msg").format(
pub=i["publishedTime"],
dur=i["duration"],
vi=i["viewCount"]["short"],
clink=i["channel"]["link"],
cname=i["channel"]["name"],
)
scroll_btn = [ scroll_btn = [
[ [
InlineKeyboardButton(strings("back"), callback_data=f"ytdl_scroll|{search_key}|{page-1}"), InlineKeyboardButton(
strings("back"), callback_data=f"ytdl_scroll|{search_key}|{page-1}"
),
InlineKeyboardButton( InlineKeyboardButton(
f"{page+1}/{len(search['result'])}", f"{page+1}/{len(search['result'])}",
callback_data=f"ytdl_scroll|{search_key}|{page+1}", callback_data=f"ytdl_scroll|{search_key}|{page+1}",
@ -220,7 +263,9 @@ async def ytdl_scroll_callback(self: Client, cq: CallbackQuery, strings):
scroll_btn = [[scroll_btn.pop().pop(0)]] scroll_btn = [[scroll_btn.pop().pop(0)]]
btn = [[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")]] btn = [[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")]]
btn = InlineKeyboardMarkup(scroll_btn + btn) btn = InlineKeyboardMarkup(scroll_btn + btn)
await cq.edit_message_media(InputMediaPhoto(await get_ytthumb(i["id"]), caption=out), reply_markup=btn) await cq.edit_message_media(
InputMediaPhoto(await get_ytthumb(i["id"]), caption=out), reply_markup=btn
)
async def get_ytthumb(videoid: str): async def get_ytthumb(videoid: str):

View file

@ -1,8 +1,15 @@
import sys, os, requests # * @author Yasir Aris M <yasiramunandar@gmail.com>
from dotenv import load_dotenv # * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import os
import sys
from logging import getLogger from logging import getLogger
from os import environ from os import environ
import requests
from dotenv import load_dotenv
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
CONFIG_FILE_URL = os.environ.get("CONFIG_FILE_URL", "") CONFIG_FILE_URL = os.environ.get("CONFIG_FILE_URL", "")
@ -44,8 +51,6 @@ except Exception as e:
sys.exit(1) sys.exit(1)
USER_SESSION = environ.get("USER_SESSION") USER_SESSION = environ.get("USER_SESSION")
FF_MPEG_NAME = environ.get("FF_MPEG_NAME", "mediaextract")
VCSI_NAME = environ.get("VCSI_NAME", "ssmedia")
DATABASE_NAME = environ.get("DATABASE_NAME", "MissKatyDB") DATABASE_NAME = environ.get("DATABASE_NAME", "MissKatyDB")
TZ = environ.get("TZ", "Asia/Jakarta") TZ = environ.get("TZ", "Asia/Jakarta")
COMMAND_HANDLER = environ.get("COMMAND_HANDLER", "! /").split() COMMAND_HANDLER = environ.get("COMMAND_HANDLER", "! /").split()
@ -73,9 +78,13 @@ FORWARD_FROM_CHAT_ID = list(
} }
) )
# Forward To Chat ID # Forward To Chat ID
FORWARD_TO_CHAT_ID = list({int(x) for x in environ.get("FORWARD_TO_CHAT_ID", "-1001210537567").split()}) FORWARD_TO_CHAT_ID = list(
{int(x) for x in environ.get("FORWARD_TO_CHAT_ID", "-1001210537567").split()}
)
FORWARD_FILTERS = list(set(environ.get("FORWARD_FILTERS", "video document").split())) FORWARD_FILTERS = list(set(environ.get("FORWARD_FILTERS", "video document").split()))
BLOCK_FILES_WITHOUT_EXTENSIONS = bool(environ.get("BLOCK_FILES_WITHOUT_EXTENSIONS", True)) BLOCK_FILES_WITHOUT_EXTENSIONS = bool(
environ.get("BLOCK_FILES_WITHOUT_EXTENSIONS", True)
)
BLOCKED_EXTENSIONS = list( BLOCKED_EXTENSIONS = list(
set( set(
environ.get( environ.get(
@ -84,5 +93,5 @@ BLOCKED_EXTENSIONS = list(
).split() ).split()
) )
) )
MINIMUM_FILE_SIZE = environ.get("MINIMUM_FILE_SIZE", None) MINIMUM_FILE_SIZE = environ.get("MINIMUM_FILE_SIZE")
CURRENCY_API = environ.get("CURRENCY_API", None) CURRENCY_API = environ.get("CURRENCY_API")

View file

@ -1,6 +1,7 @@
emoji emoji
git+https://github.com/yasirarism/pyrofork git+https://github.com/yasirarism/pyrofork
tgcrypto tgcrypto
async_pymongo
pymongo pymongo
python-dotenv python-dotenv
motor[srv]>=3.1.2 motor[srv]>=3.1.2

View file

@ -1,5 +1,8 @@
import logging
import os
from subprocess import run as srun from subprocess import run as srun
import logging, os, requests
import requests
from dotenv import load_dotenv from dotenv import load_dotenv
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
@ -32,7 +35,7 @@ if len(UPSTREAM_REPO_BRANCH) == 0:
if UPSTREAM_REPO_URL is not None: if UPSTREAM_REPO_URL is not None:
if os.path.exists(".git"): if os.path.exists(".git"):
srun(["rm", "-rf", ".git"]) srun(["rm", "-rf", ".git"], check=True)
update = srun( update = srun(
[ [
@ -46,9 +49,12 @@ if UPSTREAM_REPO_URL is not None:
&& git reset --hard origin/{UPSTREAM_REPO_BRANCH} -q" && git reset --hard origin/{UPSTREAM_REPO_BRANCH} -q"
], ],
shell=True, shell=True,
check=True,
) )
if update.returncode == 0: if update.returncode == 0:
LOGGER.error("Successfully updated with latest commit from UPSTREAM_REPO") LOGGER.error("Successfully updated with latest commit from UPSTREAM_REPO")
else: else:
LOGGER.error("Something went wrong while updating, check UPSTREAM_REPO if valid or not!") LOGGER.error(
"Something went wrong while updating, check UPSTREAM_REPO if valid or not!"
)

View file

@ -54,7 +54,7 @@ async def auto_clean():
# temp db for banned # temp db for banned
class temp(object): class temp:
ME = None ME = None
CURRENT = int(os.environ.get("SKIP", 2)) CURRENT = int(os.environ.get("SKIP", 2))
CANCEL = False CANCEL = False