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>
# * @date 2022-12-01 09:12:27
# * @lastModified 2022-12-01 09:27:31
# * @projectName MissKatyPyro
# * 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
ENV HOSTNAME yasirvps
# Set Hostname
ENV HOSTNAME misskaty
# Copy Files
COPY . .
# Set CMD Bot
CMD ["bash", "start.sh"]

View file

@ -50,7 +50,7 @@
🌱 [Ko-Fi](kofi-url)<br>
## [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
@ -108,7 +108,7 @@ pip3 install -r requirements.txt
```
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
```
bash start.sh

View file

@ -108,7 +108,7 @@ pip3 install -r requirements.txt
```
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
```
bash start.sh

View file

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

View file

@ -1,5 +1,7 @@
from pyrogram.enums import ChatType
from typing import Iterable
from pyrogram.enums import ChatType
from database import dbname
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):
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:

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):
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

View file

@ -10,7 +10,8 @@ class Database:
self.col = self.db.users
self.grp = self.db.groups
def new_user(self, id, name):
@staticmethod
def new_user(id, name):
return dict(
id=id,
name=name,
@ -20,7 +21,8 @@ class Database:
),
)
def new_group(self, id, title):
@staticmethod
def new_group(id, title):
return dict(
id=id,
title=title,
@ -84,14 +86,18 @@ class Database:
is_disabled=False,
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"):
chat_status = dict(
is_disabled=True,
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):
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
from logging import ERROR, INFO, StreamHandler, basicConfig, getLogger, handlers
from apscheduler.jobstores.mongodb import MongoDBJobStore
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from async_pymongo import AsyncClient
from motor.motor_asyncio import AsyncIOMotorClient
from pymongo import MongoClient
from pyrogram import Client
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(
level=INFO,
@ -28,9 +41,7 @@ MOD_NOLOAD = ["subscene_dl"]
HELPABLE = {}
cleanmode = {}
botStartTime = time.time()
misskaty_version = "v2.7 - Stable"
pymonclient = MongoClient(DATABASE_URI)
misskaty_version = "v2.8.7 - Stable"
# Pyrogram Bot Client
app = Client(
@ -38,7 +49,7 @@ app = Client(
api_id=API_ID,
api_hash=API_HASH,
bot_token=BOT_TOKEN,
mongodb=dict(uri=DATABASE_URI, remove_peers=False),
mongodb=dict(connection=AsyncClient(DATABASE_URI), remove_peers=False),
)
# Pyrogram UserBot Client
@ -47,7 +58,7 @@ user = Client(
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)
app.start()

View file

@ -15,27 +15,19 @@ from logging import getLogger
from pyrogram import __version__, idle
from pyrogram.raw.all import layer
from misskaty import (
BOT_NAME,
BOT_USERNAME,
HELPABLE,
UBOT_NAME,
app,
scheduler
)
from database import dbname
from misskaty import BOT_NAME, BOT_USERNAME, HELPABLE, UBOT_NAME, app, scheduler
from misskaty.plugins import ALL_MODULES
from misskaty.plugins.web_scraper import web
from misskaty.vars import SUDO, USER_SESSION
from utils import auto_clean
from database import dbname
LOGGER = getLogger(__name__)
loop = asyncio.get_event_loop()
# Run Bot
async def start_bot():
global HELPABLE
for module in ALL_MODULES:
imported_module = importlib.import_module(f"misskaty.plugins.{module}")
if hasattr(imported_module, "__MODULE__") and imported_module.__MODULE__:
@ -79,13 +71,18 @@ async def start_bot():
for key, value in web.items():
await webdb.insert_one({key: value})
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)
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())
await idle()
if __name__ == "__main__":
try:
loop.run_until_complete(start_bot())
@ -96,4 +93,6 @@ if __name__ == "__main__":
LOGGER.info(err)
finally:
loop.stop()
LOGGER.info("------------------------ Stopped Services ------------------------")
LOGGER.info(
"------------------------ Stopped Services ------------------------"
)

View file

@ -1,10 +1,10 @@
import asyncio
import os
import traceback
from functools import wraps
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.types import CallbackQuery
from misskaty import app
from misskaty.vars import LOG_CHANNEL
@ -13,6 +13,14 @@ from misskaty.vars import LOG_CHANNEL
def capture_err(func):
@wraps(func)
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:
return await func(client, message, *args, **kwargs)
except ChatWriteForbidden:
@ -21,22 +29,28 @@ def capture_err(func):
exc = traceback.format_exc()
error_feedback = "ERROR | {} | {}\n\n{}\n\n{}\n".format(
message.from_user.id if message.from_user else 0,
message.chat.id if message.chat else 0,
message.text or message.caption,
chat.id if chat else 0,
msg,
exc,
)
day = datetime.today()
day = datetime.now()
tgl_now = datetime.now()
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...")
with open(f"crash_{tgl_now.strftime('%d %B %Y')}.log", "w+", encoding="utf-8") as log:
await sender(
"😭 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.close()
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
return capture

View file

@ -1,6 +1,7 @@
import asyncio
from functools import wraps
def asyncify(func):
async def inner(*args, **kwargs):
loop = asyncio.get_running_loop()
@ -9,6 +10,7 @@ def asyncify(func):
return inner
def new_task(func):
@wraps(func)
def wrapper(*args, **kwargs):

View file

@ -1,17 +1,22 @@
from time import time
from functools import partial, wraps
from typing import Union, Optional
from time import time
from traceback import format_exc as err
from typing import Optional, Union
from pyrogram import enums, Client
from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
from ...helper.localization import default_language, get_lang, get_locale_string, langdict
from pyrogram.types import Message, CallbackQuery
from pyrogram import Client, enums
from pyrogram.errors import ChannelPrivate, ChatAdminRequired, ChatWriteForbidden
from pyrogram.types import CallbackQuery, Message
from misskaty import app
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):
perms = []
@ -40,80 +45,6 @@ async def member_permissions(chat_id: int, user_id: int):
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(
message: Union[CallbackQuery, Message],
permissions: Optional[Union[list, str]],
@ -128,7 +59,10 @@ async def check_perms(
chat = message.chat
if not message.from_user:
return bool(message.sender_chat and message.sender_chat.id == message.chat.id)
try:
user = await chat.get_member(message.from_user.id)
except ChatAdminRequired:
return False
if user.status == enums.ChatMemberStatus.OWNER:
return True
@ -156,17 +90,19 @@ admins_in_chat = {}
async def list_admins(chat_id: int):
global admins_in_chat
if chat_id in admins_in_chat:
interval = time() - admins_in_chat[chat_id]["last_updated_at"]
if interval < 3600:
return admins_in_chat[chat_id]["data"]
try:
admins_in_chat[chat_id] = {
"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"]
except ChannelPrivate:
return
async def authorised(func, subFunc2, client, message, *args, **kwargs):

View file

@ -1,6 +1,7 @@
from pyrogram import filters
import asyncio
from pyrogram import filters
data = {}
@ -13,7 +14,10 @@ async def task(msg, warn=False, sec=None):
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..")
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):

View file

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

View file

@ -1,7 +1,15 @@
import asyncio
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__)

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 io
from asyncio import get_event_loop
from asyncio import sleep as asleep
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 pyrogram.errors import (
ChatAdminRequired,
ChatWriteForbidden,
FloodWait,
MessageAuthorRequired,
MessageDeleteForbidden,
MessageIdInvalid,
MessageNotModified,
MessageTooLong,
)
from pyrogram.types import Message
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)
@ -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)
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
Example:
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())
doc = io.BytesIO(text.encode())
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:

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

View file

@ -1,10 +1,18 @@
import io
from typing import Union, Optional
from pyrogram.types import Message
from typing import Optional, Union
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
Example:
@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.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

View file

@ -1,10 +1,12 @@
from typing import Union
from pyrogram.types import Message
from pyrogram import Client
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.
Example:
@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
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:
@ -24,7 +32,7 @@ class PyromodConfig:
stopped_handler = None
throw_exceptions = 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):
@ -36,12 +44,80 @@ def patch(obj):
old = getattr(obj, name, None)
if old is not None: # Not adding 'old' to new func
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)
return container
return wrapper
def patchable(func):
def patchable(
is_property: bool = False, is_static: bool = False, is_context: bool = False
) -> 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 pyrate_limiter import BucketFullException, Duration, Limiter, MemoryListBucket, RequestRate
from pyrate_limiter import (
BucketFullException,
Duration,
Limiter,
MemoryListBucket,
RequestRate,
)
class RateLimiter:
@ -11,17 +17,17 @@ class RateLimiter:
"""
def __init__(self) -> None:
# 2 requests per seconds
self.second_rate = RequestRate(2, Duration.SECOND)
# 1 requests per seconds
self.second_rate = RequestRate(1, Duration.SECOND)
# 15 requests per minute.
self.minute_rate = RequestRate(15, Duration.MINUTE)
# 500 requests per hour
self.hourly_rate = RequestRate(500, Duration.HOUR)
# 100 requests per hour
self.hourly_rate = RequestRate(100, Duration.HOUR)
# 1500 requests per day
self.daily_rate = RequestRate(1500, Duration.DAY)
# 500 requests per day
self.daily_rate = RequestRate(500, Duration.DAY)
self.limiter = Limiter(
self.minute_rate,

View file

@ -8,7 +8,7 @@ from .media_helper import *
from .misc import *
from .pyro_progress import *
from .stickerset import *
from .subscene_helper import *
from .time_gap import *
from .tools 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):
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)):
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:
for node in code:
if isinstance(node, ast.Return):
@ -56,11 +69,22 @@ async def meval(code, globs, **kwargs):
# globals().update(**<global_args>)
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)
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)
code.insert(1, ret_decl)
args = []

View file

@ -6,7 +6,6 @@ from pyrogram.errors import FloodWait
from pyrogram.types import InputMediaPhoto
from misskaty.plugins.dev import shell_exec
from misskaty.vars import VCSI_NAME, FF_MPEG_NAME
def hhmmss(seconds):
@ -15,7 +14,7 @@ def hhmmss(seconds):
async def take_ss(video_file):
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)
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):
out_put_file_name = f"{output_directory}/{str(time.time())}.png"
cmd = [
FF_MPEG_NAME,
"ffmpeg",
"-ss",
str(ttl),
"-i",

View file

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

View file

@ -1,16 +1,20 @@
import re
import traceback
import chevron
import logging
import traceback
from html import escape
from telegraph.aio import Telegraph
from misskaty.helper.http import http
from misskaty import BOT_USERNAME
import chevron
from bs4 import BeautifulSoup
from telegraph.aio import Telegraph
from misskaty import BOT_USERNAME
from misskaty.helper.http import http
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):
@ -24,25 +28,89 @@ async def kusonimeBypass(url: str, slug=None):
soup = BeautifulSoup(page.text, "lxml")
thumb = soup.find("div", {"class": "post-thumb"}).find("img").get("src")
data = []
# title = soup.select("#venkonten > div.vezone > div.venser > div.venutama > div.lexot > p:nth-child(3) > strong")[0].text.strip()
try:
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()
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()
season = (
soup.select(
"#venkonten > div.vezone > div.venser > div.venutama > div.lexot > div.info > p:nth-child(3)"
)[0]
.text.split(":")
.pop()
.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:
e = traceback.format_exc()
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 = []
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(", ")
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": []}
for smokeurl in smokedl.find_all("div", {"class": "smokeurlrh"}):
quality = smokeurl.find("strong").text
@ -109,7 +177,9 @@ async def byPassPh(url: str, name: str):
telegraph = Telegraph()
if not telegraph.get_access_token():
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"]}'}
del results["error_message"]
return results
@ -117,10 +187,12 @@ async def byPassPh(url: str, name: str):
class Kusonime:
def __init__(self):
pass
raise NotImplementedError()
async def byPass(self, url):
@staticmethod
async def byPass(url):
return await kusonimeBypass(url)
async def telegraph(self, url, name):
@staticmethod
async def telegraph(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] = [
# "en-GB", # English (United Kingdom)
"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-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"

View file

@ -3,9 +3,10 @@ import os
import shlex
from typing import Tuple
from misskaty import BOT_USERNAME
from telegraph.aio import Telegraph
from misskaty import BOT_USERNAME
async def post_to_telegraph(is_media: bool, title=None, content=None, media=None):
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)
return f"https://telegra.ph{response[0]['src']}"
"""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"]

View file

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

View file

@ -6,7 +6,7 @@ import asyncio
import math
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):

View file

@ -1,11 +1,11 @@
import logging
import os
import random
import string
import time
import logging
from http.cookies import SimpleCookie
from urllib.parse import urlparse
from re import match as re_match
from urllib.parse import urlparse
import psutil
@ -15,7 +15,7 @@ from misskaty.helper.human_read import get_readable_time
from misskaty.plugins import ALL_MODULES
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 = {
"Action": "👊",
"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.
"""
import asyncio
import re
import os
import re
from logging import getLogger
from time import time
from pyrogram import enums, filters, Client
from pyrogram import Client, enums, filters
from pyrogram.errors import ChatAdminRequired, FloodWait
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 (
admins_in_chat,
adminsOnly,
require_admin,
list_admins,
member_permissions,
require_admin,
)
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb
from misskaty.helper.localization import use_chat_lang
from misskaty.helper.functions import (
extract_user,
extract_user_and_reason,
int_to_alpha,
time_converter,
)
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, SUDO
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)):
return await ctx.reply_msg(strings("kick_admin_err"))
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":
await ctx.reply_to_message.delete_msg()
try:
@ -210,7 +215,11 @@ async def banFunc(client, message, strings):
except IndexError:
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":
await message.reply_to_message.delete()
if message.command[0] == "tban":
@ -313,7 +322,13 @@ async def list_ban_(c, message, strings):
count += 1
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)
@ -507,7 +522,10 @@ async def mute(client, message, strings):
return await message.reply_text(strings("mute_admin_err"))
mention = (await app.get_users(user_id)).mention
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":
split = reason.split(None, 1)
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))
else:
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 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
new_title = ctx.text.split(None, 1)[1]
await ctx.chat.set_title(new_title)
await ctx.reply_text(
f"Successfully Changed Group Title From {old_title} To {new_title}"
)
await ctx.reply_text(f"Successfully Changed Group Title From {old_title} To {new_title}")
@app.on_message(filters.command("set_user_title", COMMAND_HANDLER) & ~filters.private)
@adminsOnly("can_change_info")
async def set_user_title(self: Client, ctx: Message):
if not ctx.reply_to_message:
return await ctx.reply_text(
"Reply to user's message to set his admin title"
)
return await ctx.reply_text("Reply to user's message to set his admin title")
if not ctx.reply_to_message.from_user:
return await ctx.reply_text(
"I can't change admin title of an unknown entity"
)
return await ctx.reply_text("I can't change admin title of an unknown entity")
chat_id = ctx.chat.id
from_user = ctx.reply_to_message.from_user
if len(ctx.command) < 2:
return await ctx.reply_text(
"**Usage:**\n/set_user_title NEW ADMINISTRATOR TITLE"
)
return await ctx.reply_text("**Usage:**\n/set_user_title NEW ADMINISTRATOR TITLE")
title = ctx.text.split(None, 1)[1]
await app.set_administrator_title(chat_id, from_user.id, title)
await ctx.reply_text(
f"Successfully Changed {from_user.mention}'s Admin Title To {title}"
)
await ctx.reply_text(f"Successfully Changed {from_user.mention}'s Admin Title To {title}")
@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
if not file:
return await ctx.reply_text(
"Reply to a photo or document to set it as chat_photo"
)
return await ctx.reply_text("Reply to a photo or document to set it as chat_photo")
if file.file_size > 5000000:
return await ctx.reply("File size too large.")
photo = await reply.download()
await ctx.chat.set_photo(photo)
file = await reply.download()
try:
await ctx.chat.set_photo(photo=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.
#
# Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import time
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 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 = (
await ctx.reply_animation(
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"
else await ctx.reply_animation(
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":
send = (
await ctx.reply_photo(
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"
else await ctx.reply_photo(
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":
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,
)
elif afktype == "text_reason":
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,
)
except Exception:
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,
)
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)
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)
@ -194,7 +217,9 @@ async def afk_state(self: Client, ctx: Message, strings):
if not ctx.from_user:
return
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
state = ctx.text.split(None, 1)[1].strip()
state = state.lower()
@ -223,8 +248,10 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
possible = ["/afk", f"/afk@{self.me.username}", "!afk"]
message_text = ctx.text or ctx.caption
for entity in ctx.entities:
if entity.type == enums.MessageEntityType.BOT_COMMAND:
if (message_text[0 : 0 + entity.length]).lower() in possible:
if (
entity.type == enums.MessageEntityType.BOT_COMMAND
and (message_text[0 : 0 + entity.length]).lower() in possible
):
return
msg = ""
@ -241,30 +268,42 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
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":
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 str(reasonafk) == "None":
send = await ctx.reply_animation(
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:
send = await ctx.reply_animation(
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 str(reasonafk) == "None":
send = await ctx.reply_photo(
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:
send = await ctx.reply_photo(
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:
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"]
seenago = get_readable_time2((int(time.time() - timeafk)))
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":
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 str(reasonafk) == "None":
send = await ctx.reply_animation(
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:
send = await ctx.reply_animation(
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 str(reasonafk) == "None":
send = await ctx.reply_photo(
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:
send = await ctx.reply_photo(
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:
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:
pass
@ -338,33 +404,56 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
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":
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 str(reasonafk) == "None":
send = await ctx.reply_animation(
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:
send = await ctx.reply_animation(
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 str(reasonafk) == "None":
send = await ctx.reply_photo(
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:
send = await ctx.reply_photo(
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:
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:
try:
user_id = entity[j].user.id
@ -384,30 +473,51 @@ async def afk_watcher_func(self: Client, ctx: Message, strings):
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
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":
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 str(reasonafk) == "None":
send = await ctx.reply_animation(
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:
send = await ctx.reply_animation(
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 str(reasonafk) == "None":
send = await ctx.reply_photo(
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:
send = await ctx.reply_photo(
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:
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 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()
@ -168,7 +171,6 @@ async def anime_search(_, mesg):
variables = {"search": search}
if not (res := json.loads(await get_anime(variables))["data"].get("Media", None)):
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"
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"]:

View file

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

View file

@ -20,7 +20,9 @@ LOGGER = getLogger(__name__)
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
if (len(FORWARD_FILTERS) == 9) or (
(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):
_file = media.file_name.rsplit(".", 1)
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:
return False
@ -70,15 +75,17 @@ async def ForwardMessage(client: user, msg: Message):
if file_size_passed is False:
return 400
## --- Check 4 --- ##
for i in range(len(FORWARD_TO_CHAT_ID)):
for item in FORWARD_TO_CHAT_ID:
try:
await msg.copy(FORWARD_TO_CHAT_ID[i])
await msg.copy(item)
except FloodWait as e:
await sleep(e.value)
LOGGER.warning(f"#FloodWait: Stopped Forwarder for {e.x}s!")
await ForwardMessage(client, msg)
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:
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 database.users_chats_db import db
from misskaty import app
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)
@ -12,8 +13,12 @@ async def ban_reply(self: Client, ctx: Message):
if not ctx.from_user:
return
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):
await ctx.reply_msg(f'I am sorry, You are banned to use Me. \nBan Reason: {ban["ban_reason"]}')
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
):
await ctx.reply_msg(
f'I am sorry, You are banned to use Me. \nBan Reason: {ban["ban_reason"]}'
)
await ctx.stop_propagation()
@ -23,16 +28,23 @@ async def grp_bd(self: Client, ctx: Message, strings):
if not ctx.from_user:
return
if not await db.is_chat_exist(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"
await self.send_message(
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)
chck = await db.get_chat(ctx.chat.id)
if chck['is_disabled']:
buttons = [[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]]
if chck["is_disabled"]:
buttons = [
[InlineKeyboardButton("Support", url=f"https://t.me/{SUPPORT_CHAT}")]
]
reply_markup = InlineKeyboardMarkup(buttons)
vazha = await db.get_chat(ctx.chat.id)
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))
async def ban_a_user(bot, message):
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)
if len(r) > 2:
reason = message.text.split(None, 2)[2]
@ -65,31 +77,29 @@ async def ban_a_user(bot, message):
try:
k = await bot.get_users(chat)
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:
return await message.reply("This might be a channel, make sure its a user.")
except Exception as e:
return await message.reply(f'Error - {e}')
return await message.reply(f"Error - {e}")
else:
jar = await db.get_ban_status(k.id)
if jar['is_banned']:
return await message.reply(f"{k.mention} is already banned\nReason: {jar['ban_reason']}")
if jar["is_banned"]:
return await message.reply(
f"{k.mention} is already banned\nReason: {jar['ban_reason']}"
)
await db.ban_user(k.id, reason)
await message.reply(f"Successfully banned user {k.mention}!! Reason: {reason}")
@app.on_message(filters.command("unbanuser", COMMAND_HANDLER) & filters.user(SUDO))
async def unban_a_user(bot, message):
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)
if len(r) > 2:
reason = message.text.split(None, 2)[2]
chat = message.text.split(None, 2)[1]
else:
chat = message.command[1]
reason = "No reason Provided"
chat = message.text.split(None, 2)[1] if len(r) > 2 else message.command[1]
try:
chat = int(chat)
except:
@ -97,14 +107,16 @@ async def unban_a_user(bot, message):
try:
k = await bot.get_users(chat)
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:
return await message.reply("This might be a channel, make sure its a user.")
except Exception as e:
return await message.reply(f'Error - {e}')
return await message.reply(f"Error - {e}")
else:
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.")
await db.remove_ban(k.id)
await message.reply(f"Successfully unbanned user {k.mention}!!!")
@ -129,11 +141,15 @@ async def disable_chat(bot, message):
if not cha_t:
return await message.reply("Chat Not Found In DB")
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 message.reply("Chat Succesfully Disabled")
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)
await bot.send_message(
chat_id=chat_,

View file

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

View file

@ -10,14 +10,14 @@ import urllib.parse
from urllib.parse import unquote
import requests
from pyrogram import filters, Client
from pyrogram import Client, filters
from pyrogram.errors import EntitiesTooLong, MessageTooLong
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from misskaty import app
from misskaty.core.decorator.errors import capture_err
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
LIST_LINK = """
@ -94,7 +94,6 @@ async def bypass(self: Client, ctx: Message):
if len(ctx.command) == 1:
return await ctx.reply_msg(f"Gunakan perintah /{ctx.command[0]} untuk bypass url", del_in=6)
url = ctx.command[1]
urllib.parse.urlparse(url).netloc
msg = await ctx.reply_msg("Bypassing URL..", quote=True)
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):

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 html
import openai
from aiohttp import ClientSession
from pyrogram import filters, Client
from pyrogram.types import Message
from pyrogram import Client, filters
from pyrogram.errors import MessageTooLong
from pyrogram.types import Message
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.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
openai.api_key = OPENAI_API
# This only for testing things, since maybe in future it will got blocked
@app.on_message(filters.command("bard", COMMAND_HANDLER))
@use_chat_lang()
@ -22,13 +28,17 @@ async def bard_chatbot(self: Client, ctx: Message, strings):
if len(ctx.command) == 1:
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)
data = {'message': ctx.input, 'session_id':'XQjzKRYITZ7fhplF-rXa_GTynUwdctKq4aGm-lqUCCJzF98xqDulL9UKopIadNpQn0lvnA.'}
data = {
"message": ctx.input,
"session_id": "XQjzKRYITZ7fhplF-rXa_GTynUwdctKq4aGm-lqUCCJzF98xqDulL9UKopIadNpQn0lvnA.",
}
try:
req = await http.post("https://bard-api-rho.vercel.app/ask", json=data)
await msg.edit_msg(req.json().get("content"))
except Exception as e:
await msg.edit_msg(str(e))
@app.on_message(filters.command("ask", COMMAND_HANDLER))
@ratelimiter
@use_chat_lang()
@ -45,7 +55,12 @@ async def openai_chatbot(self: Client, ctx: Message, strings):
num = 0
answer = ""
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:
if not chunk.choices[0].delta or chunk.choices[0].delta.get("role"):
continue
@ -58,7 +73,10 @@ async def openai_chatbot(self: Client, ctx: Message, strings):
await msg.edit_msg(answer)
except MessageTooLong:
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:
await msg.edit_msg(f"ERROR: {str(err)}")
await openai.aiosession.get().close()

View file

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

View file

@ -3,8 +3,8 @@ from pyrogram.errors import UserIsBlocked, UserNotParticipant
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
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.ratelimiter import ratelimiter
from misskaty.vars import COMMAND_HANDLER

View file

@ -1,11 +1,16 @@
from pyrogram import filters, Client
from pyrogram.types import Message
from misskaty import app
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import logging
from pyrogram import Client, filters
from pyrogram.types import Message
from misskaty import app
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER, CURRENCY_API
__MODULE__ = "Currency"
__HELP__ = """
/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,
)
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()
amount = teks[1]
currency_from = teks[2]
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}"
try:
res = await http.get(url)
@ -41,7 +49,9 @@ async def currency(self: Client, ctx: Message):
last_update = data["time_last_update_utc"]
except KeyError:
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:
await ctx.reply_msg(f"Failed convert currency, maybe you give wrong currency format or api down.\n\n<b>ERROR</b>: {err}")
else:

View file

@ -1,44 +1,47 @@
import asyncio
import contextlib
import html
import io
import json
import os
import pickle
import re
import sys
import html
import pickle
import json
import traceback
import cloudscraper
import aiohttp
import logging
from datetime import datetime
from inspect import getfullargspec
from shutil import disk_usage
from time import time
from database.users_chats_db import db
from inspect import getfullargspec
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
from psutil import disk_usage as disk_usage_percent
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
import aiohttp
import cloudscraper
from PIL import Image, ImageDraw, ImageFont
from misskaty import app, user, botStartTime, misskaty_version, BOT_NAME
from misskaty.helper.http import http
from misskaty.helper.eval_helper import meval, format_exception
from misskaty.helper.localization import use_chat_lang
from misskaty.helper.functions import (
extract_user,
extract_user_and_reason
from psutil import Process, boot_time, cpu_count, cpu_percent
from psutil import disk_usage as disk_usage_percent
from psutil import net_io_counters, virtual_memory
from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import Client
from pyrogram import __version__ as pyrover
from pyrogram import enums, filters
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.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"
__HELP__ = """
@ -102,19 +105,25 @@ async def log_file(self: Client, ctx: Message, strings) -> "Message":
async def donate(client, ctx):
keyboard = InlineKeyboard(row_width=2)
keyboard.add(
InlineButton('QR QRIS [Yasir Store]', url='https://telegra.ph/file/2acf7698f300ef3d9138f.jpg'),
InlineButton('Sociabuzz', url='https://sociabuzz.com/yasirarism/tribe'),
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'),
InlineButton(
"QR QRIS [Yasir Store]",
url="https://telegra.ph/file/2acf7698f300ef3d9138f.jpg",
),
InlineButton("Sociabuzz", url="https://sociabuzz.com/yasirarism/tribe"),
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(
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":
pesan = ctx.input
await ctx.delete_msg()
@ -244,14 +253,11 @@ async def ban_globally(self: Client, ctx: Message):
await asyncio.sleep(int(e.value))
except Exception:
pass
try:
with contextlib.suppress(Exception):
await app.send_message(
user_id,
f"Hello, You have been globally banned by {from_user.mention},"
+ " You can appeal for this ban by talking to him.",
f"Hello, You have been globally banned by {from_user.mention}, You can appeal for this ban by talking to him.",
)
except Exception:
pass
await m.edit(f"Banned {user_mention} Globally!")
ban_text = f"""
__**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.'")
@app.on_message(filters.command(["shell", "sh", "term"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_edited_message(filters.command(["shell", "sh", "term"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_message(
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)
@use_chat_lang()
async def shell(self: Client, ctx: Message, strings) -> "Message":
if len(ctx.command) == 1:
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]
if len(shell) > 3000:
with io.BytesIO(str.encode(shell)) as doc:
@ -332,7 +346,16 @@ async def shell(self: Client, ctx: Message, strings) -> "Message":
ctx,
text=html.escape(shell),
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:
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)
@app.on_message((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))
@app.on_message(
(
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)
@use_chat_lang()
async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
if (ctx.command and len(ctx.command) == 1) or ctx.text == "app.run()":
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)
code = ctx.text.split(" ", 1)[1] if ctx.command else ctx.text.split("\napp.run()")[0]
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)
)
code = (
ctx.text.split(" ", 1)[1] if ctx.command else ctx.text.split("\napp.run()")[0]
)
out_buf = io.StringIO()
out = ""
humantime = get_readable_time
@ -365,6 +403,10 @@ async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
kwargs["file"] = out_buf
return print(*args, **kwargs)
def _help(*args: Any, **kwargs: Any) -> None:
with contextlib.redirect_stdout(out_buf):
help(*args, **kwargs)
eval_vars = {
"self": self,
"humantime": humantime,
@ -383,6 +425,7 @@ async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
"traceback": traceback,
"http": http,
"replied": ctx.reply_to_message,
"help": _help,
}
eval_vars.update(var)
eval_vars.update(teskode)
@ -446,7 +489,16 @@ async def cmd_eval(self: Client, ctx: Message, strings) -> Optional[str]:
ctx,
text=final_output,
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:
await status_message.delete_msg()
@ -475,15 +527,28 @@ async def updtebot(client, update, users, chats):
user = users[update.user_id]
if update.stopped and await db.is_user_exist(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):
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)
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]
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 math
import os
@ -37,7 +41,12 @@ __HELP__ = """
async def upload(bot, message):
if not message.reply_to_message:
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)
if not media:
return await message.reply("Unsupported media type..")
@ -70,7 +79,12 @@ async def download(client, message):
if message.reply_to_message is not None:
start_t = datetime.now()
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)
if not media:
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.start()
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()
try:
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 re
import os
import shutil
from apscheduler.schedulers.asyncio import AsyncIOScheduler
@ -9,21 +12,22 @@ from pyrogram.errors import PeerIdInvalid, UserNotParticipant
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
from .web_scraper import SCRAP_DICT, data_kuso
from .pypi_search import PYPI_DICT
from .ytdl_plugins import YT_DB
from utils import temp
from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.permissions import admins_in_chat
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 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]
REQUEST_DB = {}
@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} 😇")
@ -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))
async def start(_, message):
async def thankregex(_, message):
pesan = [
f"Sama-sama {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 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.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb
from misskaty.helper.functions import extract_text_and_keyb
@ -47,7 +52,10 @@ You can use markdown or html to save text too.
@ratelimiter
async def save_filters(_, m):
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:
return await m.reply_msg("__**You can only save text or stickers in filters for now.**__")
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 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.ratelimiter import ratelimiter
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
@ -160,13 +160,13 @@ async def memify(client, message):
hapus(png)
except:
pass
await message.reply(f"ERROR: {err}")
await message.reply_msg(f"ERROR: {err}")
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))
@use_chat_lang()
async def dice(c, m, strings):
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
* Copyright @YasirPedia All rights reserved
"""
import math
import os
import time
import math
from asyncio import gather, sleep
from datetime import datetime
from logging import getLogger
from pySmartDL import SmartDL
from urllib.parse import unquote
from pyrogram import enums, filters, Client
from pyrogram import Client, enums, filters
from pyrogram.errors import FloodWait
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.core.decorator import ratelimiter, new_task
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.core.decorator import new_task, ratelimiter
from misskaty.helper import is_url, progress_for_pyrogram, take_ss
from misskaty.helper.localization import use_chat_lang
from misskaty.helper.pyro_progress import humanbytes
@ -109,7 +108,11 @@ async def genss(self: Client, ctx: Message, strings):
]
)
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,
)
await pesan.delete()
@ -165,7 +168,11 @@ async def genss(self: Client, ctx: Message, strings):
]
)
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,
)
await process.delete()

View file

@ -11,11 +11,11 @@ from pyrogram.types import ChatMemberUpdated, InlineKeyboardButton, InlineKeyboa
from database.users_chats_db import db
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.ratelimiter import ratelimiter
from misskaty.helper.http import http
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
LOGGER = getLogger(__name__)
@ -43,7 +43,9 @@ def draw_multiple_line_text(image, text, font, text_start_height):
lines = textwrap.wrap(text, width=50)
for line in lines:
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
@ -53,9 +55,15 @@ def welcomepic(pic, user, chat, id, strings):
background = background.resize((1024, 500), Image.ANTIALIAS)
pfp = Image.open(pic).convert("RGBA")
pfp = circle(pfp)
pfp = pfp.resize((265, 265)) # 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
pfp = pfp.resize(
(265, 265)
) # 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, chat, font, 47)
ImageDraw.Draw(background).text(
@ -65,15 +73,25 @@ def welcomepic(pic, user, chat, id, strings):
size=20,
align="right",
)
background.paste(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
background.paste(
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"
@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()
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
user = member.new_chat_member.user if member.new_chat_member else member.from_user
if user.id in SUDO:
@ -92,15 +110,21 @@ async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
pass
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")
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
dc = user.dc_id or "Member tanpa PP"
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:
pic = "assets/profilepic.png"
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(
member.chat.id,
photo=welcomeimg,
@ -111,19 +135,35 @@ async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
userspammer = ""
# Spamwatch Detection
try:
headers = {"Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"}
apispamwatch = (await http.get(f"https://api.spamwat.ch/banlist/{user.id}", headers=headers)).json()
headers = {
"Authorization": "Bearer XvfzE4AUNXkzCy0DnIVpFDlxZi79lt6EnwKgBj8Quuzms0OSdHvf1k6zSeyzZ_lz"
}
apispamwatch = (
await http.get(
f"https://api.spamwat.ch/banlist/{user.id}", headers=headers
)
).json()
if not apispamwatch.get("error"):
await app.ban_chat_member(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"))
await app.ban_chat_member(
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:
LOGGER.error(f"ERROR in Spamwatch Detection. {err}")
# Combot API Detection
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":
await app.ban_chat_member(member.chat.id, user.id, datetime.now() + timedelta(seconds=30))
userspammer += strings("combot_msg").format(umention=user.mention, uid=user.id)
await app.ban_chat_member(
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:
LOGGER.error(f"ERROR in Combot API Detection. {err}")
if userspammer != "":
@ -140,7 +180,9 @@ async def member_has_joined(c: app, member: ChatMemberUpdated, strings):
async def greet_group(bot, message, strings):
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")
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:
@ -149,28 +191,48 @@ async def greet_group(bot, message, strings):
except:
pass
try:
welcomeimg = await welcomepic(pic, u.first_name, message.chat.title, u.id, strings)
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),
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()
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"))
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()
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)
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 != "":
@ -192,9 +254,11 @@ async def leave_a_chat(bot, message):
try:
chat = int(chat)
except:
chat = chat
pass
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)
await bot.send_message(
chat_id=chat,
@ -220,7 +284,9 @@ async def gen_invite(bot, message):
try:
link = await bot.create_chat_invite_link(chat)
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:
return await message.reply(f"Error {e}")
await message.reply(f"Here is your Invite Link {link.invite_link}")
@ -235,12 +301,16 @@ async def adminlist(_, message):
try:
msg = await message.reply_msg(f"Getting admin list in {message.chat.title}..")
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 ""
administrators.append(f"{m.user.first_name} [{uname}]")
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:
await message.reply(f"ERROR: {str(e)}")
@ -259,7 +329,9 @@ async def kickme(_, message):
await message.reply_text(txt)
await message.chat.unban_member(message.from_user.id)
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:
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 logging
import re
import traceback
from bs4 import BeautifulSoup
from urllib.parse import quote_plus
from utils import demoji
from bs4 import BeautifulSoup
from deep_translator import GoogleTranslator
from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import filters, enums, Client
from pyrogram.errors import MediaEmpty, MessageNotModified, PhotoInvalidDimensions, WebpageMediaEmpty, MessageIdInvalid
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message, CallbackQuery
from pyrogram import Client, enums, filters
from pyrogram.errors import (
MediaCaptionTooLong,
MediaEmpty,
MessageIdInvalid,
MessageNotModified,
PhotoInvalidDimensions,
WebpageMediaEmpty,
)
from pyrogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
InputMediaPhoto,
Message,
)
from database.imdb_db import *
from misskaty import BOT_USERNAME, app
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.helper import http, get_random_string, search_jw, GENRES_EMOJI
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
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__)
LIST_CARI = {}
@ -32,10 +47,13 @@ headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWe
@ratelimiter
async def imdb_choose(self: Client, ctx: Message):
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:
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)
if is_imdb:
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)
except ListenerTimeout:
del LIST_CARI[ranval]
try:
await msg.edit_caption("😶‍🌫️ Callback Query Timeout. Task Has Been Canceled!")
except MessageIdInvalid:
pass
@app.on_callback_query(filters.regex("^imdbset"))
@ratelimiter
async def imdbsetlang(self: Client, query: CallbackQuery):
@capture_err
async def imdblangset(self: Client, query: CallbackQuery):
i, uid = query.data.split("#")
if query.from_user.id != int(uid):
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}"))
msg = await query.message.edit_caption("<i>Please select available language below..</i>", reply_markup=buttons)
try:
await msg.wait_for_click(
from_user_id=int(uid),
timeout=30
)
await msg.wait_for_click(from_user_id=int(uid), timeout=30)
except ListenerTimeout:
try:
await msg.edit_caption("😶‍🌫️ Callback Query Timeout. Task Has Been Canceled!")
except MessageIdInvalid:
pass
@app.on_callback_query(filters.regex("^setimdb"))
@ratelimiter
@capture_err
async def imdbsetlang(self: Client, query: CallbackQuery):
i, lang, uid = query.data.split("#")
if query.from_user.id != int(uid):
@ -119,7 +142,10 @@ async def imdb_search_id(kueri, message):
msg = ""
buttons = InlineKeyboard(row_width=4)
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")
if not res:
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)
msg = await k.edit_caption(msg, reply_markup=buttons)
try:
await msg.wait_for_click(
from_user_id=message.from_user.id,
timeout=30
)
await msg.wait_for_click(from_user_id=message.from_user.id, timeout=30)
except ListenerTimeout:
try:
await msg.edit_caption("😶‍🌫️ Waktu Habis. Task Telah Dibatalkan!")
except MessageIdInvalid:
pass
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>")
@ -176,7 +202,10 @@ async def imdb_search_en(kueri, message):
msg = ""
buttons = InlineKeyboard(row_width=4)
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")
if not res:
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)
msg = await k.edit_caption(msg, reply_markup=buttons)
try:
await msg.wait_for_click(
from_user_id=message.from_user.id,
timeout=30
)
await msg.wait_for_click(from_user_id=message.from_user.id, timeout=30)
except ListenerTimeout:
try:
await msg.edit_caption("😶‍🌫️ Timeout. Task Has Been Cancelled!")
except MessageIdInvalid:
pass
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>")
@app.on_callback_query(filters.regex("^imdbcari"))
@ratelimiter
@capture_err
async def imdbcari(self: Client, query: CallbackQuery):
BTN = []
i, lang, msg, uid = query.data.split("#")
@ -240,7 +270,10 @@ async def imdbcari(self: Client, query: CallbackQuery):
msg = ""
buttons = InlineKeyboard(row_width=4)
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")
if not res:
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)
msg = await query.message.edit_caption(msg, reply_markup=buttons)
try:
await msg.wait_for_click(
from_user_id=int(uid),
timeout=30
)
await msg.wait_for_click(from_user_id=int(uid), timeout=30)
except ListenerTimeout:
try:
await msg.edit_caption("😶‍🌫️ Waktu Habis. Task Telah Dibatalkan!")
except MessageIdInvalid:
pass
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>")
else:
@ -286,7 +319,10 @@ async def imdbcari(self: Client, query: CallbackQuery):
msg = ""
buttons = InlineKeyboard(row_width=4)
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")
if not res:
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)
msg = await query.message.edit_caption(msg, reply_markup=buttons)
try:
await msg.wait_for_click(
from_user_id=int(uid),
timeout=30
)
await msg.wait_for_click(from_user_id=int(uid), timeout=30)
except ListenerTimeout:
try:
await msg.edit_caption("😶‍🌫️ Timeout. Task Has Been Cancelled!")
except MessageIdInvalid:
pass
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>")
@app.on_callback_query(filters.regex("^imdbres_id"))
@ratelimiter
@capture_err
async def imdb_id_callback(self: Client, query: CallbackQuery):
i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid):
@ -372,7 +409,7 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
for i in directors:
name = i["name"]
url = i["url"]
director += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
director += f"<a href='{url}'>{name}</a>, "
director = director[:-2]
res_str += f"<b>Sutradara:</b> {director}\n"
if creators := r_json.get("creator"):
@ -381,7 +418,7 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
if i["@type"] == "Person":
name = i["name"]
url = i["url"]
creator += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
creator += f"<a href='{url}'>{name}</a>, "
creator = creator[:-2]
res_str += f"<b>Penulis:</b> {creator}\n"
if actor := r_json.get("actor"):
@ -389,7 +426,7 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
for i in actor:
name = i["name"]
url = i["url"]
actors += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
actors += f"<a href='{url}'>{name}</a>, "
actors = actors[:-2]
res_str += f"<b>Pemeran:</b> {actors}\n\n"
if deskripsi := r_json.get("description"):
@ -416,33 +453,38 @@ async def imdb_id_callback(self: Client, query: CallbackQuery):
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton("🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"),
InlineKeyboardButton("🎬 Open IMDB", url=url),
InlineKeyboardButton("▶️ Trailer", url=trailer_url),
]
]
)
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"):
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):
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:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
else:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
except (MessageNotModified, MessageIdInvalid):
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"))
@ratelimiter
@capture_err
async def imdb_en_callback(self: Client, query: CallbackQuery):
i, userid, movie = query.data.split("#")
if query.from_user.id != int(userid):
@ -491,7 +533,7 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
for i in directors:
name = i["name"]
url = i["url"]
director += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
director += f"<a href='{url}'>{name}</a>, "
director = director[:-2]
res_str += f"<b>Director:</b> {director}\n"
if creators := r_json.get("creator"):
@ -500,7 +542,7 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
if i["@type"] == "Person":
name = i["name"]
url = i["url"]
creator += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
creator += f"<a href='{url}'>{name}</a>, "
creator = creator[:-2]
res_str += f"<b>Writer:</b> {creator}\n"
if actor := r_json.get("actor"):
@ -508,7 +550,7 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
for i in actor:
name = i["name"]
url = i["url"]
actors += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
actors += f"<a href='{url}'>{name}</a>, "
actors = actors[:-2]
res_str += f"<b>Stars:</b> {actors}\n\n"
if description := r_json.get("description"):
@ -534,26 +576,30 @@ async def imdb_en_callback(self: Client, query: CallbackQuery):
markup = InlineKeyboardMarkup(
[
[
InlineKeyboardButton("🎬 Open IMDB", url=f"https://www.imdb.com{r_json['url']}"),
InlineKeyboardButton("🎬 Open IMDB", url=url),
InlineKeyboardButton("▶️ Trailer", url=trailer_url),
]
]
)
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"):
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):
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:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
else:
await query.message.edit_caption(res_str, parse_mode=enums.ParseMode.HTML, reply_markup=markup)
except (MessageNotModified, MessageIdInvalid):
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 re
import traceback
@ -8,7 +12,7 @@ from sys import version as pyver
from bs4 import BeautifulSoup
from deep_translator import GoogleTranslator
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 enums, filters
from pyrogram.errors import MessageIdInvalid, MessageNotModified
@ -23,7 +27,7 @@ from pyrogram.types import (
from misskaty import BOT_USERNAME, app, user
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 utils import demoji
@ -47,7 +51,12 @@ LOGGER = getLogger()
async def inline_menu(_, inline_query: InlineQuery):
if inline_query.query.strip().lower().strip() == "":
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)
bot_state = "Alive" if await app.get_me() else "Dead"
@ -71,21 +80,27 @@ async def inline_menu(_, inline_query: InlineQuery):
InlineQueryResultArticle(
title="Inline Commands",
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",
reply_markup=buttons,
),
InlineQueryResultArticle(
title="Github Repo",
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",
),
InlineQueryResultArticle(
title="Alive",
description="Check Bot's Stats",
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,
),
]
@ -98,7 +113,10 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline",
)
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(
"https://github.com/PaulSonOfLars/telegram-bot-api-spec/raw/main/api.json",
headers=headers,
@ -114,7 +132,10 @@ async def inline_menu(_, inline_query: InlineQuery):
buttons = InlineKeyboard()
buttons.row(
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(
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"])
msg = f"<b>{method}</b> (<code>{returns[:-2]}</code>)\n"
msg += f"{description}\n\n"
msg += f"<b>Variables:</b>\n"
msg += "<b>Variables:</b>\n"
if parsemethod[method].get("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"
@ -152,14 +173,17 @@ async def inline_menu(_, inline_query: InlineQuery):
buttons = InlineKeyboard()
buttons.row(
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(
InlineButton("Give Coffee", url="https://yasirpedia.eu.org"),
)
msg = f"<b>{types}</b>\n"
msg += f"{description}\n\n"
msg += f"<b>Variables:</b>\n"
msg += "<b>Variables:</b>\n"
if parsetypes[types].get("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"
@ -199,15 +223,21 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline",
)
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"}
search_results = await http.get(f"https://www.google.com/search?q={judul}&num=20", headers=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")
data = []
for result in soup.find_all("div", class_="kvH3mc BToiNc UK95Uc"):
link = result.find("div", class_ ="yuRUbf").find("a").get("href")
title = result.find("div", class_ ="yuRUbf").find("h3").get_text()
link = result.find("div", class_="yuRUbf").find("a").get("href")
title = result.find("div", class_="yuRUbf").find("h3").get_text()
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:
snippet = "-"
message_text = f"<a href='{link}'>{title}</a>\n"
@ -223,7 +253,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link,
description=snippet,
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(
@ -250,7 +282,9 @@ async def inline_menu(_, inline_query: InlineQuery):
except Exception: # pylint: disable=broad-except
inline_query.stop_propagation()
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"
if diaa.username:
msg += f"<b>🌐 Username:</b> <code>@{diaa.username}</code>\n"
@ -298,7 +332,11 @@ async def inline_menu(_, inline_query: InlineQuery):
)
prvte_msg = InlineKeyboardMarkup(
[
[InlineKeyboardButton("Show Message 🔐", callback_data=f"prvtmsg({inline_query.id})")],
[
InlineKeyboardButton(
"Show Message 🔐", callback_data=f"prvtmsg({inline_query.id})"
)
],
[
InlineKeyboardButton(
"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>"
msg_c = f"🔒 A <b>private message</b> to {mention} [<code>{penerima.id}</code>], "
mention = (
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."
results = [
InlineQueryResultArticle(
@ -328,7 +372,9 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline",
)
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)
item = srch_results.get("items")
data = []
@ -351,7 +397,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link,
description=deskripsi,
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(
@ -391,7 +439,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link,
description=deskripsi,
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(
@ -410,7 +460,9 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline",
)
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)
asroe = srch_results.get("results")
oorse = []
@ -422,7 +474,9 @@ async def inline_menu(_, inline_query: InlineQuery):
durasi = sraeo.get("accessibility").get("duration")
publishTime = sraeo.get("publishedTime")
try:
deskripsi = "".join(f"{i['text']} " for i in sraeo.get("descriptionSnippet"))
deskripsi = "".join(
f"{i['text']} " for i in sraeo.get("descriptionSnippet")
)
except:
deskripsi = "-"
message_text = f"<a href='{link}'>{title}</a>\n"
@ -441,7 +495,9 @@ async def inline_menu(_, inline_query: InlineQuery):
url=link,
description=deskripsi,
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(
@ -460,7 +516,9 @@ async def inline_menu(_, inline_query: InlineQuery):
switch_pm_parameter="inline",
)
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")
oorse = []
for midb in res:
@ -469,7 +527,11 @@ async def inline_menu(_, inline_query: InlineQuery):
stars = midb.get("s", "")
imdb_url = f"https://imdb.com/title/{midb.get('id')}"
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='{imdb_url}'>{title} {year}</a>"
oorse.append(
@ -543,41 +605,78 @@ async def imdb_inl(_, query):
i, user, movie = query.data.split("#")
if user == f"{query.from_user.id}":
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}/"
resp = await get_content(url)
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")
res_str = ""
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"
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:
res_str += "\n"
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"
if r_json.get("contentRating"):
res_str += f"<b>Kategori:</b> <code>{r_json['contentRating']}</code> \n"
if r_json.get("aggregateRating"):
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"]'):
rilis = 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"]
rilis = (
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"
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]
res_str += f"<b>Genre:</b> {genre}\n"
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]
res_str += f"<b>Negara:</b> {country}\n"
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]
res_str += f"<b>Bahasa:</b> {language}\n"
res_str += "\n<b>🙎 Info Cast:</b>\n"
@ -586,7 +685,7 @@ async def imdb_inl(_, query):
for i in r_json["director"]:
name = i["name"]
url = i["url"]
director += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
director += f"<a href='{url}'>{name}</a>, "
director = director[:-2]
res_str += f"<b>Sutradara:</b> {director}\n"
if r_json.get("creator"):
@ -595,7 +694,7 @@ async def imdb_inl(_, query):
if i["@type"] == "Person":
name = i["name"]
url = i["url"]
creator += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
creator += f"<a href='{url}'>{name}</a>, "
creator = creator[:-2]
res_str += f"<b>Penulis:</b> {creator}\n"
if r_json.get("actor"):
@ -603,11 +702,13 @@ async def imdb_inl(_, query):
for i in r_json["actor"]:
name = i["name"]
url = i["url"]
actors += f"<a href='https://www.imdb.com{url}'>{name}</a>, "
actors += f"<a href='{url}'>{name}</a>, "
actors = actors[:-2]
res_str += f"<b>Pemeran:</b> {actors}\n\n"
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"
if r_json.get("keywords"):
keywords = r_json["keywords"].split(",")
@ -618,7 +719,11 @@ async def imdb_inl(_, query):
key_ = key_[:-2]
res_str += f"<b>🔥 Kata Kunci:</b> {key_} \n"
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"
else:
res_str += "\n"
@ -632,7 +737,7 @@ async def imdb_inl(_, query):
[
InlineKeyboardButton(
"🎬 Buka IMDB",
url=f"https://www.imdb.com{r_json['url']}",
url=url,
),
InlineKeyboardButton("▶️ Trailer", url=trailer_url),
]
@ -644,12 +749,14 @@ async def imdb_inl(_, query):
[
InlineKeyboardButton(
"🎬 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):
pass
except Exception:

View file

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

View file

@ -9,10 +9,12 @@ from pyrogram.types import (
InlineKeyboardMarkup,
Message,
)
from misskaty.vars import COMMAND_HANDLER
from misskaty import app
from database.locale_db import set_db_lang
from misskaty import app
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.vars import COMMAND_HANDLER
from ..core.decorator.permissions import require_admin
from ..helper.localization import (
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")
msg = await sender(res, reply_markup=keyboard)
try:
await msg.wait_for_click(
from_user_id=m.from_user.id,
timeout=30
)
await msg.wait_for_click(from_user_id=m.from_user.id, timeout=30)
except ListenerTimeout:
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:
await app.set_chat_permissions(message.chat.id, ChatPermissions(**permissions))
except ChatNotModified:
return await message.reply_text(
"To unlock this, you have to unlock 'messages' first."
)
return await message.reply_text("To unlock this, you have to unlock 'messages' first.")
await message.reply_text(("Locked." if lock else "Unlocked."))
@ -178,7 +176,4 @@ async def url_detector(_, message):
try:
await message.delete_msg()
except Exception:
await message.reply_msg(
"This message contains a URL, "
+ "but i don't have enough permissions to delete it"
)
await message.reply_msg("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 urllib.parse import unquote
from pyrogram import filters, Client
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message, CallbackQuery
from pyrogram import Client, filters
from pyrogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
Message,
)
from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
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.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.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.vars import COMMAND_HANDLER, FF_MPEG_NAME
from misskaty.vars import COMMAND_HANDLER
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)),
reply_markup=InlineKeyboardMarkup(buttons),
)
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:
await msg.edit_msg(strings("exp_task", context="general"))
except Exception:
@ -120,12 +122,7 @@ async def ceksub(self: Client, ctx: Message, strings):
@use_chat_lang()
async def convertsrt(self: Client, ctx: Message, strings):
reply = ctx.reply_to_message
if (
not reply
or not reply.document
or not reply.document.file_name
or not reply.document.file_name.endswith((".vtt", ".ass", ".srt"))
):
if 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)
msg = await ctx.reply_msg(strings("convert_str"), quote=True)
if not os.path.exists("downloads"):
@ -134,7 +131,7 @@ async def convertsrt(self: Client, ctx: Message, strings):
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}]")
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()
await ctx.reply_document(
f"downloads/{filename}.{suffix}",
@ -177,7 +174,7 @@ async def stream_extract(self: Client, update: CallbackQuery, strings):
namafile = get_subname(lang, link, ext)
try:
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
c_time = time()
await update.message.reply_document(

View file

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

View file

@ -1,16 +1,14 @@
"""
* @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
import asyncio
import json
import os
import asyncio
import traceback
from PIL import Image
from logging import getLogger
from urllib.parse import quote
@ -18,6 +16,7 @@ import aiohttp
from bs4 import BeautifulSoup
from deep_translator import GoogleTranslator
from gtts import gTTS
from PIL import Image
from pyrogram import Client, filters
from pyrogram.errors import MessageTooLong, UserNotParticipant
from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup
@ -69,7 +68,10 @@ async def readqr(c, m):
os.remove(foto)
if res := r.json()[0]["symbol"][0]["data"] is None:
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))
@ -80,9 +82,13 @@ async def makeqr(c, m):
elif len(m.command) > 1:
teks = m.text.split(None, 1)[1]
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"
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))
@ -90,13 +96,21 @@ async def makeqr(c, m):
async def stackoverflow(client, message):
if len(message.command) == 1:
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..")
hasil = ""
for count, data in enumerate(r["items"], start=1):
question = data["question_id"]
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"
try:
await msg.edit(hasil)
@ -116,7 +130,9 @@ async def gsearch(client, message):
query = message.text.split(" ", maxsplit=1)[1]
msg = await message.reply_text(f"**Googling** for `{query}` ...")
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(
f"https://www.google.com/search?q={query}&gl=id&hl=id&num=17",
headers=headers,
@ -127,10 +143,12 @@ async def gsearch(client, message):
data = []
for result in soup.find_all("div", class_="kvH3mc BToiNc UK95Uc"):
link = result.find("div", class_ ="yuRUbf").find("a").get("href")
title = result.find("div", class_ ="yuRUbf").find("h3").get_text()
link = result.find("div", class_="yuRUbf").find("a").get("href")
title = result.find("div", class_="yuRUbf").find("h3").get_text()
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:
snippet = "-"
@ -145,7 +163,9 @@ async def gsearch(client, message):
arr = json.dumps(data, indent=2, ensure_ascii=False)
parse = json.loads(arr)
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:
exc = traceback.format_exc()
return await msg.edit(exc)
@ -159,7 +179,9 @@ async def gsearch(client, message):
@capture_err
@ratelimiter
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]
text = message.reply_to_message.text or message.reply_to_message.caption
else:
@ -173,10 +195,14 @@ async def translate(client, message):
try:
my_translator = GoogleTranslator(source="auto", target=target_lang)
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:
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:
await msg.edit_msg(f"Oppss, Error: <code>{str(err)}</code>")
@ -185,7 +211,9 @@ async def translate(client, message):
@capture_err
@ratelimiter
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:
target_lang = "id"
else:
@ -239,12 +267,21 @@ async def topho(client, message):
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")
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()
im = Image.open(photo).convert("RGB")
filename = f"toimg_{message.from_user.id}.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(filename)
except Exception as e:
@ -278,10 +315,16 @@ async def showid(client, message):
)
file_info = get_file_id(message.reply_to_message)
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)
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)
@ -316,12 +359,20 @@ async def who_is(client, message):
try:
chat_member_p = await message.chat.get_member(from_user.id)
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:
pass
if chat_photo := from_user.photo:
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)
await message.reply_photo(
photo=local_user_photo,
@ -332,7 +383,13 @@ async def who_is(client, message):
)
os.remove(local_user_photo)
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)
await message.reply_text(
text=message_out_str,
@ -358,7 +415,9 @@ async def close_callback(bot: Client, query: CallbackQuery):
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):
@ -369,8 +428,7 @@ async def get_content(url):
async def mdlapi(title):
link = f"https://kuryana.vercel.app/search/q/{title}"
async with aiohttp.ClientSession() as ses:
async with ses.get(link) as result:
async with aiohttp.ClientSession() as ses, ses.get(link) as result:
return await result.json()
@ -412,16 +470,22 @@ async def mdl_callback(bot: Client, query: CallbackQuery):
try:
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>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>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>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":
result += f"<b>Release Date:</b> <code>{res['data']['details']['release_date']}</code>\n"
elif res["data"]["details"]["type"] == "Drama":
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:
result += f"<b>Aired on:</b> <code>{res['data']['details']['aired_on']}</code>\n"
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"
except:
pass
result += 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>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>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)
except Exception as e:
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 re
from datetime import datetime, timedelta
import pytz
from apscheduler.jobstores.base import ConflictingIdError
from pyrogram import filters, __version__
from pyrogram.errors import ChannelInvalid, ChannelPrivate, ChatAdminRequired, ChatNotModified
from pyrogram import __version__, filters
from pyrogram.errors import (
ChannelInvalid,
ChannelPrivate,
ChatAdminRequired,
ChatNotModified,
)
from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup
from database.locale_db import get_db_lang
from misskaty import BOT_NAME, app, scheduler
from misskaty.core.decorator.ratelimiter import ratelimiter
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
__MODULE__ = "NightMode"
@ -92,19 +101,32 @@ async def un_mute_chat(chat_id: int, perm: ChatPermissions):
try:
await app.set_chat_permissions(chat_id, perm)
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):
scheduler.remove_job(f"enable_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:
pass
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:
job = scheduler.get_job(f"enable_nightmode_{chat_id}")
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):
@ -113,19 +135,32 @@ async def mute_chat(chat_id: int):
try:
await app.set_chat_permissions(chat_id, ChatPermissions())
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):
scheduler.remove_job(f"enable_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:
pass
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:
job = scheduler.get_job(f"disable_nightmode_{chat_id}")
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)
@ -163,10 +198,28 @@ async def nightmode_handler(c, msg, strings):
end_time_stamp = start_timestamp + timedelta(seconds=int(lock_dur))
try:
# 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
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:
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))
@ -178,4 +231,7 @@ async def nightmode_handler(c, msg, strings):
@ratelimiter
@use_chat_lang()
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 misskaty import app
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.ratelimiter import ratelimiter
from misskaty.core.keyboard import ikb
from misskaty.helper.functions import extract_text_and_keyb
@ -64,7 +64,6 @@ async def save_notee(_, message):
"type": _type,
"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
await save_note(chat_id, name, note)
await message.reply(f"__**Saved note {name}.**__")
@ -74,7 +73,6 @@ async def save_notee(_, message):
@capture_err
@ratelimiter
async def get_notes(_, message):
message.text.split()[0][0]
chat_id = message.chat.id
_notes = await get_note_names(chat_id)
@ -123,7 +121,6 @@ async def del_note(_, message):
if not name:
return await message.reply("**Usage**\n__/delnote [NOTE_NAME]__")
message.text.split()[0][0]
chat_id = message.chat.id
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
from PIL import Image, ImageDraw, ImageFont
from pyrogram import filters
from misskaty import app
from misskaty.vars import COMMAND_HANDLER
from PIL import Image, ImageFont, ImageDraw
from pyrogram import filters
__MODULE__ = "nulis"
__HELP__ = """
Command: <code>/nulis</code> [reply to msg or after cmd]
Desc: For those of you who are lazy to write.
Command: <code>/nulis</code> [reply to msg or after cmd]
Desc: For those of you who are lazy to write.
"""
def text_set(text):
lines = []
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))
return lines[:25]
@app.on_message(filters.command(["nulis"], COMMAND_HANDLER))
async def handwrite(client, message):
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"
img.save(file)
if os.path.exists(file):
await message.reply_photo(
photo=file, caption=f"<b>Written By :</b> {client.me.mention}"
)
await message.reply_photo(photo=file, caption=f"<b>Written By :</b> {client.me.mention}")
os.remove(file)
await nan.delete()
except Exception as e:

View file

@ -1,7 +1,6 @@
"""
* @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27
* @lastModified 2022-12-01 09:32:31
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
@ -9,15 +8,15 @@
import os
from pyrogram import filters, Client
from pyrogram import Client, filters
from pyrogram.types import Message
from telegraph.aio import Telegraph
from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
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.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "OCR"
@ -30,15 +29,7 @@ __HELP__ = "/ocr [reply to photo] - Read Text From Image"
@use_chat_lang()
async def ocr(self: Client, ctx: Message, strings):
reply = ctx.reply_to_message
if (
not reply
or not reply.sticker
and not reply.photo
and (
not reply.document
or not reply.document.mime_type.startswith("image")
)
):
if 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)
msg = await ctx.reply_msg(strings("read_ocr"), quote=True)
try:

View file

@ -13,7 +13,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app
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
__MODULE__ = "Paste"
@ -32,7 +32,7 @@ def humanbytes(size: int):
"""Convert Bytes To Bytes So That Human Can Read It"""
if not isinstance(size, int):
try:
size = size
pass
except ValueError:
size = None
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):
reply = message.reply_to_message
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.username:
@ -89,21 +92,35 @@ async def telegraph_paste(_, message):
return msg.edit_msg(f"Failed to upload. ERR: {err}")
button = [
[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}**"
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 = ""
limit = 1024 * 1024
if reply and reply.document:
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):
return await msg.edit_msg("**Only text files can be pasted.**")
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:
with open(file, "r") as text:
data = text.read()
@ -115,8 +132,14 @@ async def telegraph_paste(_, message):
pass
return await msg.edit_msg("`File Not Supported !`")
elif reply and (reply.text or reply.caption):
title = 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>")
title = (
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:
title = "MissKaty Paste"
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")
button = [
[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}**"
@ -144,14 +171,18 @@ async def wastepaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
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...`")
data = ""
limit = 1024 * 1024
if reply and reply.document:
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):
return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download()
@ -195,7 +226,11 @@ async def wastepaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems")
button = [
[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}**"
@ -209,14 +244,18 @@ async def nekopaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
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...`")
data = ""
limit = 1024 * 1024
if reply and reply.document:
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):
return await message.edit_msg("**Only text files can be pasted.**")
file = await reply.download()
@ -239,12 +278,16 @@ async def nekopaste(_, message):
if message.from_user.username:
uname = f"@{message.from_user.username}"
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:
uname = message.sender_chat.title
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']}"
except Exception as 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")
button = [
[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}**"
@ -267,14 +314,18 @@ async def spacebinn(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
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...`")
data = ""
limit = 1024 * 1024
if reply and reply.document:
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):
return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download()
@ -297,7 +348,9 @@ async def spacebinn(_, message):
if message.from_user.username:
uname = f"@{message.from_user.username}"
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:
uname = message.sender_chat.title
@ -313,7 +366,11 @@ async def spacebinn(_, message):
return await msg.edit_msg("Text Too Short Or File Problems")
button = [
[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}**"
@ -327,14 +384,18 @@ async def rentrypaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
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...`")
data = ""
limit = 1024 * 1024
if reply and reply.document:
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):
return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download()
@ -357,7 +418,9 @@ async def rentrypaste(_, message):
if message.from_user.username:
uname = f"@{message.from_user.username}"
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:
uname = message.sender_chat.title
@ -370,7 +433,11 @@ async def rentrypaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems")
button = [
[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}**"
@ -384,14 +451,18 @@ async def tempaste(_, message):
reply = message.reply_to_message
target = str(message.command[0]).split("@", maxsplit=1)[0]
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...`")
data = ""
limit = 1024 * 1024
if reply and reply.document:
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):
return await msg.edit_msg("**Only text files can be pasted.**")
file = await reply.download()
@ -414,7 +485,9 @@ async def tempaste(_, message):
if message.from_user.username:
uname = f"@{message.from_user.username}"
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:
uname = message.sender_chat.title
@ -438,7 +511,11 @@ async def tempaste(_, message):
return await msg.edit_msg("Text Too Short Or File Problems")
button = [
[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}**"

View file

@ -4,20 +4,20 @@
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
import time
import os
import platform
import time
from asyncio import Lock
from re import MULTILINE, findall
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 misskaty import app, botStartTime, misskaty_version
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.human_read import get_readable_time
from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER
@ -29,7 +29,9 @@ async def ping(self: Client, ctx: Message):
rm = await ctx.reply_msg("🐱 Pong!!...")
end_t = time.time()
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))

View file

@ -1,18 +1,17 @@
"""
* @author yasir <yasiramunandar@gmail.com>
* @date 2023-01-23 19:41:27
* @lastModified 2023-01-23 19:41:31
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
from pykeyboard import InlineButton, InlineKeyboard
from pyrogram import filters, Client
from pyrogram.types import Message, CallbackQuery
from pyrogram import Client, filters
from pyrogram.types import CallbackQuery, Message
from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
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
PYPI_DICT = {}
@ -77,7 +76,11 @@ async def pypipage_callback(self: Client, callback_query: CallbackQuery):
return
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(*btn)
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..")
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:
html = await http.get(f"https://pypi.org/pypi/{pkgname}/json", headers=headers)
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 pyrogram import Client, filters
from pyrogram.types import Message
from misskaty import app
from misskaty.helper.http import http
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
__MODULE__ = "Fun"
__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.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):
return
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)
msg = ""
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")
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)
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:
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:
lastname_before = lastname_before 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)
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 != "":
await ctx.reply_msg(msg, quote=True)

View file

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

View file

@ -2,15 +2,29 @@ import traceback
from logging import getLogger
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 telethon import TelegramClient
from misskaty.core.misskaty_patch.listen.listen import ListenerTimeout
from telethon.errors import ApiIdInvalidError, PasswordHashInvalidError, PhoneCodeExpiredError, PhoneCodeInvalidError, PhoneNumberInvalidError, SessionPasswordNeededError
from telethon.errors import (
ApiIdInvalidError,
PasswordHashInvalidError,
PhoneCodeExpiredError,
PhoneCodeInvalidError,
PhoneNumberInvalidError,
SessionPasswordNeededError,
)
from telethon.sessions import StringSession
from misskaty import app
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
LOGGER = getLogger(__name__)
@ -38,12 +52,19 @@ gen_button = [[InlineKeyboardButton(text="🙄 Generate Session 🙄", callback_
async def is_batal(msg):
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
elif msg.text == "/skip":
return False
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
else:
return False
@ -87,8 +108,10 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
if is_bot:
ty += " Bot"
await msg.reply(f"» Trying to start **{ty}** session generator...")
msg.chat.id
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)
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,
)
if await is_batal(api_id_msg):
return
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)
await api_id_msg.delete()
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)
if await is_batal(api_hash_msg):
return
@ -118,7 +145,13 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
if telethon and is_bot or telethon:
client = TelegramClient(StringSession(), api_id, api_hash)
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:
client = Client(name="user", api_id=api_id, api_hash=api_hash, in_memory=True)
await client.connect()
@ -130,17 +163,30 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
else:
code = await client.send_code(phone_number)
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):
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:
phone_code_msg = None
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):
return
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:
phone_code = phone_code_msg.text.replace(" ", "")
await phone_code_msg.delete()
@ -150,14 +196,27 @@ async def generate_session(bot, msg, telethon=False, is_bot: bool = False):
else:
await client.sign_in(phone_number, code.phone_code_hash, phone_code)
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):
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):
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:
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:
password = two_step_msg.text
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):
return
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:
await client.start(bot_token=phone_number)
else:

View file

@ -6,16 +6,20 @@
* Copyright @YasirPedia All rights reserved
"""
import re
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message, CallbackQuery
from database.users_chats_db import db
from pyrogram import filters, Client
from pyrogram.errors import ChannelPrivate
from misskaty import app, BOT_USERNAME, HELPABLE, BOT_NAME
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
from pyrogram import Client, filters
from pyrogram.types import (
CallbackQuery,
InlineKeyboardButton,
InlineKeyboardMarkup,
Message,
)
from misskaty import BOT_NAME, BOT_USERNAME, HELPABLE, app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import bot_sys_stats, paginate_modules
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
home_keyboard_pm = InlineKeyboardMarkup(
[
@ -68,35 +72,20 @@ keyboard = InlineKeyboardMarkup(
@use_chat_lang()
async def start(self: Client, ctx: Message, strings):
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
return await ctx.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=strings("start_msg").format(kamuh=nama),
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:
name = (ctx.text.split(None, 1)[1]).lower()
if "_" in name:
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)
elif name == "help":
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()
async def help_command(self: Client, ctx: Message, strings):
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:
name = (ctx.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE:
@ -165,18 +146,13 @@ async def help_command(self: Client, ctx: Message, strings):
await ctx.reply_msg(strings("pm_detail"), reply_markup=keyboard)
else:
await ctx.reply_msg(strings("pm_detail"), reply_markup=keyboard)
else:
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.command) >= 2:
elif 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__
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)
@ -187,7 +163,9 @@ async def help_command(self: Client, ctx: Message, strings):
)
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)
await ctx.reply_msg(
text, reply_markup=help_keyboard, disable_web_page_preview=True
)
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)
back_match = re.match(r"help_back", 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:
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(
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,
)
elif home_match:
@ -238,7 +223,9 @@ async def help_button(self: Client, query: CallbackQuery, strings):
curr_page = int(prev_match[1])
await query.message.edit_msg(
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,
)
@ -246,7 +233,9 @@ async def help_button(self: Client, query: CallbackQuery, strings):
next_page = int(next_match[1])
await query.message.edit_msg(
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,
)

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 os
import re
@ -5,19 +9,29 @@ import shutil
import tempfile
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.file_id import FileId
from pyrogram.raw.functions.messages import GetStickerSet, SendMedia
from pyrogram.raw.functions.stickers import AddStickerToSet, CreateStickerSet, RemoveStickerFromSet
from pyrogram.raw.types import DocumentAttributeFilename, InputDocument, InputMediaUploadedDocument, InputStickerSetItem, InputStickerSetShortName
from pyrogram.raw.functions.stickers import (
AddStickerToSet,
CreateStickerSet,
RemoveStickerFromSet,
)
from pyrogram.raw.types import (
DocumentAttributeFilename,
InputDocument,
InputMediaUploadedDocument,
InputStickerSetItem,
InputStickerSetShortName,
)
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from misskaty import BOT_USERNAME, app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
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"
__HELP__ = """
@ -76,7 +90,7 @@ async def getstickerid(self: Client, ctx: Message):
@app.on_message(filters.command("unkang", COMMAND_HANDLER) & filters.reply)
@ratelimiter
@use_chat_lang()
async def getstickerid(self: Client, ctx: Message, strings):
async def unkangs(self: Client, ctx: Message, strings):
if not ctx.from_user:
return await ctx.reply("You're anon, unkang in my PM")
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)
webm_video = os.path.join(downpath, f"{f_name.split('.', 1)[0]}.webm")
cmd = [
FF_MPEG_NAME,
"ffmpeg",
"-loglevel",
"quiet",
"-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 logging
import os
@ -108,7 +112,11 @@ async def subsceneCMD(self: Client, ctx: Message):
if not subres:
return
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(*btn1)
if btn2:
@ -138,7 +146,11 @@ async def subpage_callback(self: Client, callback_query: CallbackQuery):
return
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(*btn1)
if btn2:
@ -169,7 +181,11 @@ async def subdlpage_callback(self: Client, callback_query: CallbackQuery):
return
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(*btn1)
if btn2:
@ -198,5 +214,8 @@ async def dlsub_callback(self: Client, callback_query: CallbackQuery):
res = await down_page(link)
dl = scraper.get(res.get("download_url"))
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")

View file

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

View file

@ -1,6 +1,6 @@
from pykeyboard import InlineKeyboard
from pyrogram import Client, filters
from pyrogram.types import Message, CallbackQuery
from pyrogram.types import CallbackQuery, Message
from misskaty import app
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):
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:
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:
index = int(CurrentPage - 1)
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 "[]")
return (UDFReasult, PageLen)
except IndexError or 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)
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,
)
@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)
@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
async def ud_callback(self: Client, callback_query: CallbackQuery):
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
from asyncio import gather
from pyrogram import filters, Client
from pyrogram import Client, filters
from pyrogram.types import Message
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"
downloader = SmartDL(url, download_file_path, progress_bar=False, timeout=10)
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()
os.remove(download_file_path)
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 re import compile as recompile
from uuid import uuid4
from iytdl import iYTDL, main, Process
from iytdl.exceptions import DownloadFailedError
from iytdl import Process, iYTDL, main
from iytdl.constants import YT_VID_URL
from pyrogram import filters, Client
from pyrogram.types import CallbackQuery, InlineKeyboardButton, InlineKeyboardMarkup, InputMediaPhoto, Message
from iytdl.exceptions import DownloadFailedError
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.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.misskaty_patch.listen.listen import ListenerTimeout
from misskaty.helper.http import http
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__)
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 = {}
@ -42,7 +52,13 @@ async def ytsearch(self: Client, ctx: Message, strings):
return await ctx.reply_msg(strings("no_res").format(kweri=query))
i = search["result"][0]
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(
[
[
@ -51,7 +67,11 @@ async def ytsearch(self: Client, ctx: Message, strings):
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"])
@ -60,7 +80,10 @@ async def ytsearch(self: Client, ctx: Message, strings):
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
@ratelimiter
@use_chat_lang()
@ -70,7 +93,9 @@ async def ytdownv2(self: Client, ctx: Message, strings):
if ctx.command and len(ctx.command) == 1:
return await ctx.reply_msg(strings("invalid_link"))
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:
x = await ytdl.parse(url, extract=True)
if x is None:
@ -78,11 +103,10 @@ async def ytdownv2(self: Client, ctx: Message, strings):
caption = x.caption
markup = x.buttons
photo = x.image_url
msg = await ctx.reply_photo(photo, caption=caption, reply_markup=markup, quote=True)
await msg.wait_for_click(
from_user_id=ctx.from_user.id,
timeout=30
msg = await ctx.reply_photo(
photo, caption=caption, reply_markup=markup, quote=True
)
await msg.wait_for_click(from_user_id=ctx.from_user.id, timeout=30)
except ListenerTimeout:
await msg.edit_caption(strings("exp_task", context="general"))
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:
return await cq.answer(strings("unauth"), True)
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])
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"))
@ -109,7 +137,9 @@ async def ytdl_extractinfo_callback(self: Client, cq: CallbackQuery, strings):
return await cq.answer(strings("unauth"), True)
await cq.answer(strings("wait"))
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:
if data := await ytdl.extract_info_from_key(callback[1]):
if len(callback[1]) == 11:
@ -142,7 +172,7 @@ async def ytdl_gendl_callback(self: Client, cq: CallbackQuery, strings):
async with iYTDL(
log_group_id=LOG_CHANNEL,
cache_path="cache",
ffmpeg_location=f"/usr/bin/{FF_MPEG_NAME}",
ffmpeg_location="/usr/bin/ffmpeg",
delete_media=True,
) as ytdl:
try:
@ -170,7 +200,12 @@ async def ytdl_gendl_callback(self: Client, cq: CallbackQuery, strings):
except DownloadFailedError as e:
await cq.edit_message_caption(f"Download Failed - {e}")
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"))
@ -202,10 +237,18 @@ async def ytdl_scroll_callback(self: Client, cq: CallbackQuery, strings):
search = await main.VideosSearch(query).next()
i = search["result"][page]
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 = [
[
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(
f"{page+1}/{len(search['result'])}",
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)]]
btn = [[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")]]
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):

View file

@ -1,8 +1,15 @@
import sys, os, requests
from dotenv import load_dotenv
# * @author Yasir Aris M <yasiramunandar@gmail.com>
# * @date 2023-06-21 22:12:27
# * @projectName MissKatyPyro
# * Copyright ©YasirPedia All rights reserved
import os
import sys
from logging import getLogger
from os import environ
import requests
from dotenv import load_dotenv
LOGGER = getLogger(__name__)
CONFIG_FILE_URL = os.environ.get("CONFIG_FILE_URL", "")
@ -44,8 +51,6 @@ except Exception as e:
sys.exit(1)
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")
TZ = environ.get("TZ", "Asia/Jakarta")
COMMAND_HANDLER = environ.get("COMMAND_HANDLER", "! /").split()
@ -73,9 +78,13 @@ FORWARD_FROM_CHAT_ID = list(
}
)
# 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()))
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(
set(
environ.get(
@ -84,5 +93,5 @@ BLOCKED_EXTENSIONS = list(
).split()
)
)
MINIMUM_FILE_SIZE = environ.get("MINIMUM_FILE_SIZE", None)
CURRENCY_API = environ.get("CURRENCY_API", None)
MINIMUM_FILE_SIZE = environ.get("MINIMUM_FILE_SIZE")
CURRENCY_API = environ.get("CURRENCY_API")

View file

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

View file

@ -1,5 +1,8 @@
import logging
import os
from subprocess import run as srun
import logging, os, requests
import requests
from dotenv import load_dotenv
LOGGER = logging.getLogger(__name__)
@ -32,7 +35,7 @@ if len(UPSTREAM_REPO_BRANCH) == 0:
if UPSTREAM_REPO_URL is not None:
if os.path.exists(".git"):
srun(["rm", "-rf", ".git"])
srun(["rm", "-rf", ".git"], check=True)
update = srun(
[
@ -46,9 +49,12 @@ if UPSTREAM_REPO_URL is not None:
&& git reset --hard origin/{UPSTREAM_REPO_BRANCH} -q"
],
shell=True,
check=True,
)
if update.returncode == 0:
LOGGER.error("Successfully updated with latest commit from UPSTREAM_REPO")
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
class temp(object):
class temp:
ME = None
CURRENT = int(os.environ.get("SKIP", 2))
CANCEL = False