diff --git a/locales/en-US/chatbot_ai.json b/locales/en-US/chatbot_ai.json
index ce9adf1b..21a82135 100644
--- a/locales/en-US/chatbot_ai.json
+++ b/locales/en-US/chatbot_ai.json
@@ -1,5 +1,6 @@
{
"no_question": "Please use command /{cmd} [question] to ask your question.",
"find_answers_str": "Wait a moment looking for your answer..",
+ "dont_spam": "Don't spam please, please wait {tm} second or i will ban you from this bot.",
"answers_too_long": "Question for your answer has exceeded TG text limit, check this link to view.\n\n{answerlink}"
}
\ No newline at end of file
diff --git a/locales/en-US/sub_extractor.json b/locales/en-US/sub_extractor.json
new file mode 100644
index 00000000..bb15631d
--- /dev/null
+++ b/locales/en-US/sub_extractor.json
@@ -0,0 +1,16 @@
+{
+ "sub_extr_help": "Please use command /{cmd} [link] to check subtitles or audio in video file.",
+ "conv_sub_help": "Use command /{cmd} by reply to .ass or .vtt file, to convert subtitle from .ass or .vtt to srt.",
+ "progress_str": "⏳ Processing your request..",
+ "convert_str": "⏳ Converting...",
+ "val_sec": " second",
+ "unauth_cb": "⚠️ Access Denied!",
+ "cancel_btn": "❌ Cancel",
+ "invalid_cb": "⚠️ DONT DELETE YOUR MESSAGE!",
+ "up_str": "Uploading files..",
+ "press_btn_msg": "Press the button below to extract subtitles/audio. Only support direct link at this time.\nProcessed in {timelog}",
+ "fail_extr_media": "Failed extract media, make sure your link is not protected by WAF or maybe inaccessible for bot.",
+ "fail_extr_sub": "Failed extract sub, Maybe unsupported format..\n\nLink: {link}\nERR: {e}",
+ "capt_extr_sub": "Filename: {nf}\n\nExtracted by @{bot} in {timelog}",
+ "capt_conv_sub": "{nf}.srt\n\nConverted by @{bot}"
+}
\ No newline at end of file
diff --git a/locales/id-ID/chatbot_ai.json b/locales/id-ID/chatbot_ai.json
index 5080d9a4..7e9e60ee 100644
--- a/locales/id-ID/chatbot_ai.json
+++ b/locales/id-ID/chatbot_ai.json
@@ -1,5 +1,6 @@
{
"no_question": "Harap gunakan perintah /{cmd} [question] untuk mengajukan pertanyaan Anda menggunakan OpenAI.",
"find_answers_str": "Sedang mencari jawaban terbaik buat Anda..",
+ "dont_spam": "Tolong jangan melakukan spam, harap tunggu {tm} detik atau saya akan membanned Anda dari bot ini.",
"answers_too_long": "Pertanyaan untuk jawaban Anda telah melampaui batas teks TG, periksa tautan ini untuk melihatnya.\n\n{answerlink}"
}
\ No newline at end of file
diff --git a/locales/id-ID/sub_extractor.json b/locales/id-ID/sub_extractor.json
new file mode 100644
index 00000000..73fc1743
--- /dev/null
+++ b/locales/id-ID/sub_extractor.json
@@ -0,0 +1,16 @@
+{
+ "sub_extr_help": "Harap gunakan perintah /{cmd} [tautan] untuk memeriksa teks film atau audio dalam berkas video.",
+ "conv_sub_help": "Gunakan perintah /{cmd} dengan membalas berkas .ass atau .vtt, untuk mengonversi teks film dari .ass atau .vtt ke srt.",
+ "progress_str": "⏳ Memproses permintaan Anda..",
+ "convert_str": "⏳ Mengonversi...",
+ "val_sec": " detik",
+ "unauth_cb": "⚠️ Akses Ditolak!",
+ "batal_btn": "❌ Batal",
+ "invalid_cb": "⚠️ JANGAN HAPUS PESAN ANDA!",
+ "up_str": "Mengunggah berkas..",
+ "press_btn_msg": "Tekan tombol di bawah untuk mengekstrak teks/audio. Saat ini hanya mendukung tautan langsung.\nDiproses dalam {timelog}",
+ "fail_extr_media": "Gagal mengekstrak media, pastikan tautan Anda tidak dilindungi oleh WAF atau mungkin tidak dapat diakses oleh bot.",
+ "fail_extr_sub": "Sub ekstrak gagal, Mungkin formatnya tidak didukung..\n\nTautan: {link}\nERR: {e}",
+ "capt_extr_sub": "Nama file: {nf}\n\nDiekstrak oleh @{bot} dalam {timelog}",
+ "capt_conv_sub": "{nf}.srt\n\nDikonversi oleh @{bot}"
+}
\ No newline at end of file
diff --git a/locales/id-JW/chatbot_ai.json b/locales/id-JW/chatbot_ai.json
index e674a2e2..1114acd1 100644
--- a/locales/id-JW/chatbot_ai.json
+++ b/locales/id-JW/chatbot_ai.json
@@ -1,5 +1,6 @@
{
"no_question": "Tulung gunakake printah /{cmd} [pitakon] kanggo takon nganggo fitur OpenAI.",
"find_answers_str": "Lagi goleki jawaban paling apik kanggo sampeyan..",
+ "dont_spam": "Aja spam, mangga ngenteni {tm} detik utawa aku bakal nglarang sampeyan saka bot iki.",
"answers_too_long": "Pitakonan kanggo jawaban sampeyan wis ngluwihi wates teks TG, priksa pranala iki kanggo ndeleng.\n\n{answerlink}"
}
\ No newline at end of file
diff --git a/locales/id-JW/sub_extractor.json b/locales/id-JW/sub_extractor.json
new file mode 100644
index 00000000..09d1ef39
--- /dev/null
+++ b/locales/id-JW/sub_extractor.json
@@ -0,0 +1,16 @@
+{
+ "sub_extr_help": "Gunakake printah /{cmd} [link] kanggo mriksa subtitle utawa audio ing file video.",
+ "conv_sub_help": "Gunakake printah /{cmd} kanthi mbales berkas .ass utawa .vtt, kanggo ngowahi subtitle saka .ass utawa .vtt dadi srt.",
+ "progress_str": "⏳ Ngolah panjalukmu..",
+ "convert_str": "⏳ Ngonversi...",
+ "val_sec": "Kapindho",
+ "unauth_cb": "⚠️ Akses Ditolak!",
+ "cancel_btn": "❌ Batal",
+ "invalid_cb": "⚠️ AJA Mbusak PESAN!",
+ "up_str": "Ngunggahaké berkas..",
+ "press_btn_msg": "Pencet tombol ing ngisor iki kanggo ngekstrak subtitle/audio. Mung ndhukung link langsung saiki.\nDiproses ing {timelog}",
+ "fail_extr_media": "Media ekstrak sing gagal, priksa manawa pranala sampeyan ora direksa WAF utawa ora bisa diakses kanggo bot.",
+ "fail_extr_sub": "Gagal ekstrak sub, Mungkin format ora didhukung..\n\nLink: {link}\nERR: {e}",
+ "capt_extr_sub": "Jeneng berkas: {nf}\n\nDiekstrak saka @{bot} ing {timelog}",
+ "capt_conv_sub": "{nf}.srt\n\nDiowahi dening @{bot}"
+}
\ No newline at end of file
diff --git a/misskaty/__init__.py b/misskaty/__init__.py
index 3e3c0fc1..acf1102b 100644
--- a/misskaty/__init__.py
+++ b/misskaty/__init__.py
@@ -18,6 +18,7 @@ handler = handlers.RotatingFileHandler("MissKatyLogs.txt", maxBytes=1024 * 1024)
handler.setLevel(INFO)
logger.addHandler(handler)
getLogger("pyrogram").setLevel(ERROR)
+getLogger("openai").setLevel(ERROR)
MOD_LOAD = []
MOD_NOLOAD = ["subscene_dl"]
@@ -47,11 +48,9 @@ scheduler = AsyncIOScheduler(jobstores=jobstores, timezone=TZ)
app.start()
user.start()
-bot = app.get_me()
-ubot = user.get_me()
-BOT_ID = bot.id
-BOT_NAME = bot.first_name
-BOT_USERNAME = bot.username
-UBOT_ID = ubot.id
-UBOT_NAME = ubot.first_name
-UBOT_USERNAME = ubot.username
+BOT_ID = app.id
+BOT_NAME = app.first_name
+BOT_USERNAME = app.username
+UBOT_ID = user.id
+UBOT_NAME = user.first_name
+UBOT_USERNAME = user.username
diff --git a/misskaty/core/decorator/permissions.py b/misskaty/core/decorator/permissions.py
index cdf099f7..f225ec8b 100644
--- a/misskaty/core/decorator/permissions.py
+++ b/misskaty/core/decorator/permissions.py
@@ -39,6 +39,7 @@ async def member_permissions(chat_id: int, user_id: int):
perms.append("can_manage_video_chats")
return perms
+
async def check_perms(
message: Union[CallbackQuery, Message],
permissions: Optional[Union[list, str]],
@@ -67,20 +68,52 @@ async def check_perms(
if isinstance(permissions, str):
permissions = [permissions]
- missing_perms = [
- permission
- for permission in permissions
- if not getattr(user.privileges, permission)
- ]
+ 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))
- )
+ 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]],
@@ -189,6 +222,7 @@ def adminsOnly(permission):
return subFunc
+
def require_admin(
permissions: Union[list, str] = None,
allow_in_private: bool = False,
diff --git a/misskaty/plugins/admin.py b/misskaty/plugins/admin.py
index 54f27b6d..2571124d 100644
--- a/misskaty/plugins/admin.py
+++ b/misskaty/plugins/admin.py
@@ -5,7 +5,7 @@ from time import time
from pyrogram import enums, filters
from pyrogram.errors import ChatAdminRequired, FloodWait
-from pyrogram.types import ChatPermissions, ChatPrivileges
+from pyrogram.types import ChatPermissions
from database.warn_db import add_warn, get_warn, remove_warns
from misskaty import app
diff --git a/misskaty/plugins/afk.py b/misskaty/plugins/afk.py
index 0babe409..434c4d0e 100644
--- a/misskaty/plugins/afk.py
+++ b/misskaty/plugins/afk.py
@@ -420,4 +420,4 @@ async def chat_watcher_func(client, message, strings):
try:
await put_cleanmode(message.chat.id, send.id)
except:
- pass
\ No newline at end of file
+ pass
diff --git a/misskaty/plugins/anime.py b/misskaty/plugins/anime.py
new file mode 100644
index 00000000..303b478c
--- /dev/null
+++ b/misskaty/plugins/anime.py
@@ -0,0 +1,222 @@
+import json
+from calendar import month_name
+
+import aiohttp
+from pyrogram import filters
+from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
+
+from misskaty import app
+from misskaty.helper.human_read import get_readable_time
+from misskaty.vars import COMMAND_HANDLER
+
+anime_query = """
+query ($id: Int, $idMal: Int, $search: String) {
+ Media(id: $id, idMal: $idMal, type: ANIME, search: $search) {
+ id
+ idMal
+ title {
+ romaji
+ english
+ native
+ }
+ type
+ format
+ status(version: 2)
+ description(asHtml: true)
+ startDate {
+ year
+ month
+ day
+ }
+ endDate {
+ year
+ month
+ day
+ }
+ season
+ seasonYear
+ episodes
+ duration
+ chapters
+ volumes
+ countryOfOrigin
+ source
+ hashtag
+ trailer {
+ id
+ site
+ thumbnail
+ }
+ updatedAt
+ coverImage {
+ large
+ }
+ bannerImage
+ genres
+ synonyms
+ averageScore
+ meanScore
+ popularity
+ trending
+ favourites
+ tags {
+ name
+ description
+ rank
+ }
+ relations {
+ edges {
+ node {
+ id
+ title {
+ romaji
+ english
+ native
+ }
+ format
+ status
+ source
+ averageScore
+ siteUrl
+ }
+ relationType
+ }
+ }
+ characters {
+ edges {
+ role
+ node {
+ name {
+ full
+ native
+ }
+ siteUrl
+ }
+ }
+ }
+ studios {
+ nodes {
+ name
+ siteUrl
+ }
+ }
+ isAdult
+ nextAiringEpisode {
+ airingAt
+ timeUntilAiring
+ episode
+ }
+ airingSchedule {
+ edges {
+ node {
+ airingAt
+ timeUntilAiring
+ episode
+ }
+ }
+ }
+ externalLinks {
+ url
+ site
+ }
+ rankings {
+ rank
+ year
+ context
+ }
+ reviews {
+ nodes {
+ summary
+ rating
+ score
+ siteUrl
+ user {
+ name
+ }
+ }
+ }
+ siteUrl
+ }
+}
+"""
+
+
+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})
+ return await r.read()
+
+
+def shorten(description, info="anilist.co"):
+ ms_g = ""
+ if len(description) > 700:
+ description = f"{description[:500]}...."
+ ms_g += f'\nDescription: {description}More info'
+ else:
+ ms_g += f"\nDescription: {description}"
+ return ms_g.replace("
", "").replace("", "").replace("", "").replace("", "")
+
+
+@app.on_message(filters.command("anime", COMMAND_HANDLER))
+async def anime_search(_, mesg):
+ search = mesg.text.split(" ", 1)
+ reply = await mesg.reply("⏳ Please wait ...", quote=True)
+ if len(search) == 1:
+ return await reply.edit("⚠️ Give Anime name please.")
+ else:
+ search = search[1]
+ 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"{res['title']['romaji']} ({res['title']['native']})\nType: {res['format']}\nStatus: {res['status']}\nEpisodes: {res.get('episodes', 'N/A')}\nDuration : {durasi} Per Eps.\nScore: {res['averageScore']}%\nCategory: "
+ for x in res["genres"]:
+ msg += f"{x}, "
+ msg = msg[:-2] + "\n"
+ try:
+ sd = res["startDate"]
+ startdate = str(f"{month_name[sd['month']]} {sd['day']}, {sd['year']}")
+ except:
+ startdate = "-"
+ msg += f"Start date: {startdate}\n"
+ try:
+ ed = res["endDate"]
+ enddate = str(f"{month_name[ed['month']]} {ed['day']}, {ed['year']}")
+ except:
+ enddate = "-"
+ msg += f"End date: {enddate}\n"
+ msg += "Studios: "
+ for x in res["studios"]["nodes"]:
+ msg += f"{x['name']}, "
+ msg = msg[:-2] + "\n"
+ info = res.get("siteUrl")
+ trailer = res.get("trailer", None)
+ if trailer:
+ trailer_id = trailer.get("id", None)
+ site = trailer.get("site", None)
+ if site == "youtube":
+ trailer = f"https://youtu.be/{trailer_id}"
+ description = res.get("description").replace("", "").replace("", "").replace("
", "") if res.get("description") is not None else "N/A"
+ msg += shorten(description, info)
+ image = info.replace("anilist.co/anime/", "img.anili.st/media/")
+ btn = (
+ [
+ [
+ InlineKeyboardButton("More info", url=info),
+ InlineKeyboardButton("Trailer 🎬", url=trailer),
+ ]
+ ]
+ if trailer
+ else [[InlineKeyboardButton("More info", url=info)]]
+ )
+
+ if image:
+ try:
+ await mesg.reply_photo(image, caption=msg, reply_markup=InlineKeyboardMarkup(btn))
+ except:
+ msg += f" [〽️]({image})"
+ await reply.edit(msg)
+ else:
+ await reply.edit(msg)
+ await reply.delete()
diff --git a/misskaty/plugins/bypass.py b/misskaty/plugins/bypass.py
index cf35a2aa..0a4d15b1 100644
--- a/misskaty/plugins/bypass.py
+++ b/misskaty/plugins/bypass.py
@@ -39,6 +39,7 @@ Credit: PyBypass
# Stopped development for this plugin since always changed time by time.
+
async def pling_bypass(url):
try:
id_url = re.search(r"https?://(store.kde.org|www.pling.com)\/p\/(\d+)", url)[2]
diff --git a/misskaty/plugins/chatbot_ai.py b/misskaty/plugins/chatbot_ai.py
index b5aee7f7..3868f737 100644
--- a/misskaty/plugins/chatbot_ai.py
+++ b/misskaty/plugins/chatbot_ai.py
@@ -1,12 +1,16 @@
+import openai
+from aiohttp import ClientSession
from pyrogram import filters
from pyrogram.errors import MessageTooLong
from misskaty import app
from misskaty.helper.localization import use_chat_lang
-from misskaty.helper import http, post_to_telegraph
+from misskaty.helper import post_to_telegraph, check_time_gap
from misskaty.core.message_utils import *
from misskaty.core.decorator.ratelimiter import ratelimiter
-from misskaty.vars import COMMAND_HANDLER, OPENAI_API
+from misskaty.vars import COMMAND_HANDLER, OPENAI_API, SUDO
+
+openai.api_key = OPENAI_API
@app.on_message(filters.command("ask", COMMAND_HANDLER))
@@ -15,28 +19,26 @@ from misskaty.vars import COMMAND_HANDLER, OPENAI_API
async def chatbot(c, m, strings):
if len(m.command) == 1:
return await kirimPesan(m, strings("no_question").format(cmd=m.command[0]), quote=True)
+ is_in_gap, sleep_time = await check_time_gap(m.from_user.id or m.sender_chat.id)
+ if is_in_gap and (m.from_user.id or m.sender_chat.id not in SUDO):
+ return await kirimPesan(m, strings("dont_spam"))
+ openai.aiosession.set(ClientSession())
pertanyaan = m.text.split(" ", maxsplit=1)[1]
- headers = {
- "Content-Type": "application/json",
- "Authorization": f"Bearer {OPENAI_API}",
- }
-
- json_data = {
- "model": "gpt-3.5-turbo",
- "messages": [
- {
- "role": "user",
- "content": pertanyaan,
- },
- ],
- }
msg = await kirimPesan(m, strings("find_answers_str"), quote=True)
+ num = 0
+ answer = ""
try:
- response = (await http.post("https://api.openai.com/v1/chat/completions", headers=headers, json=json_data)).json()
- if err := response.get("error"):
- return await editPesan(msg, err["message"])
- answer = response["choices"][0]["message"]["content"]
- await editPesan(msg, answer)
+ response = await openai.ChatCompletion.acreate(model="gpt-3.5-turbo", messages=[{"role": "user", "content": pertanyaan}], temperature=0.2, stream=True)
+ async for chunk in response:
+ if not chunk.choices[0].delta or chunk.choices[0].delta.get("role"):
+ continue
+ num += 1
+ answer += chunk.choices[0].delta.content
+ if num == 30:
+ await editPesan(msg, answer)
+ await asyncio.sleep(1.5)
+ num = 0
+ await openai.aiosession.get().close()
except MessageTooLong:
answerlink = await post_to_telegraph(False, "MissKaty ChatBot ", answer)
await editPesan(msg, strings("answers_too_long").format(answerlink=answerlink), disable_web_page_preview=True)
diff --git a/misskaty/plugins/dev.py b/misskaty/plugins/dev.py
index 66f11a9c..3a8e3079 100644
--- a/misskaty/plugins/dev.py
+++ b/misskaty/plugins/dev.py
@@ -207,7 +207,7 @@ async def evaluation_cmd_t(_, m, strings):
else:
evaluation = strings("success")
- final_output = f"**EVAL**:\n`{cmd}`\n\n**OUTPUT**:\n`{evaluation.strip()}`\n"
+ final_output = f"EVAL:\n{cmd}\n\nOUTPUT:\n{evaluation.strip()}\n"
if len(final_output) > 4096:
with open("MissKatyEval.txt", "w+", encoding="utf8") as out_file:
@@ -225,7 +225,7 @@ async def evaluation_cmd_t(_, m, strings):
await edit_or_reply(
m,
text=final_output,
- parse_mode=enums.ParseMode.MARKDOWN,
+ parse_mode=enums.ParseMode.HTML,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
if not m.from_user.is_self:
diff --git a/misskaty/plugins/fun.py b/misskaty/plugins/fun.py
index 7ca7ff24..d4c74e95 100644
--- a/misskaty/plugins/fun.py
+++ b/misskaty/plugins/fun.py
@@ -159,6 +159,7 @@ async def memify(client, message):
else:
await message.reply("Gunakan command /mmf 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):
diff --git a/misskaty/plugins/genss.py b/misskaty/plugins/genss.py
index 644d77b0..353eb69b 100644
--- a/misskaty/plugins/genss.py
+++ b/misskaty/plugins/genss.py
@@ -63,7 +63,7 @@ async def genss(c, m, strings):
the_real_download_location = os.path.join("/downloads/", os.path.basename(dl))
if the_real_download_location is not None:
try:
- await editPesan(process, strings("success_dl_msg"))
+ await editPesan(process, strings("success_dl_msg").format(path=the_real_download_location))
await sleep(2)
images = await take_ss(the_real_download_location)
await editPesan(process, strings("up_progress"))
diff --git a/misskaty/plugins/karma.py b/misskaty/plugins/karma.py
index 971d826b..08911f6f 100644
--- a/misskaty/plugins/karma.py
+++ b/misskaty/plugins/karma.py
@@ -13,7 +13,6 @@ from database.karma_db import (
from misskaty import app
from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.permissions import adminsOnly
-from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.functions import alpha_to_int, int_to_alpha
__MODULE__ = "Karma"
@@ -37,6 +36,7 @@ bold = lambda x: f"**{x}:** "
bold_ul = lambda x: f"**--{x}:**-- "
mono = lambda x: f"`{x}`{n}"
+
def section(
title: str,
body: dict,
@@ -46,32 +46,18 @@ def section(
text = (bold_ul(title) + n) if underline else bold(title) + n
for key, value in body.items():
- text += (
- indent * w
- + bold(key)
- + ((value[0] + n) if isinstance(value, list) else mono(value))
- )
+ text += indent * w + bold(key) + ((value[0] + n) if isinstance(value, list) else mono(value))
return text
+
async def get_user_id_and_usernames(client) -> dict:
with client.storage.lock, client.storage.conn:
- users = client.storage.conn.execute(
- 'SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null'
- ).fetchall()
- users_ = {}
- for user in users:
- users_[user[0]] = user[3]
- return users_
+ users = client.storage.conn.execute('SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null').fetchall()
+ return {user[0]: user[3] for user in users}
@app.on_message(
- filters.text
- & filters.group
- & filters.incoming
- & filters.reply
- & filters.regex(regex_upvote, re.IGNORECASE)
- & ~filters.via_bot
- & ~filters.bot,
+ filters.text & filters.group & filters.incoming & filters.reply & filters.regex(regex_upvote, re.IGNORECASE) & ~filters.via_bot & ~filters.bot,
group=karma_positive_group,
)
@capture_err
@@ -91,25 +77,15 @@ async def upvote(_, message):
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma + 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
- await message.reply_text(
- f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
- )
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
+ await message.reply_text(f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}")
@app.on_message(
- filters.text
- & filters.group
- & filters.incoming
- & filters.reply
- & filters.regex(regex_downvote, re.IGNORECASE)
- & ~filters.via_bot
- & ~filters.bot,
+ filters.text & filters.group & filters.incoming & filters.reply & filters.regex(regex_downvote, re.IGNORECASE) & ~filters.via_bot & ~filters.bot,
group=karma_negative_group,
)
@capture_err
@@ -129,28 +105,21 @@ async def downvote(_, message):
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma - 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
-
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
user_id = message.reply_to_message.from_user.id
user_mention = message.reply_to_message.from_user.mention
current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma - 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
- await message.reply_text(
- f"Decremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
- )
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
+ await message.reply_text(f"Decremented Karma of {user_mention} By 1 \nTotal Points: {karma}")
@app.on_message(filters.command("karma") & filters.group)
@@ -186,7 +155,7 @@ async def command_karma(_, message):
if int(user_idd) not in list(userdb.keys()):
continue
username = userdb[int(user_idd)]
- karma["@" + username] = ["**" + str(karma_count) + "**"]
+ karma[f"@{username}"] = [f"**{str(karma_count)}**"]
limit += 1
await m.edit(section(msg, karma))
else:
@@ -195,12 +164,8 @@ async def command_karma(_, message):
user_id = message.reply_to_message.from_user.id
karma = await get_karma(chat_id, await int_to_alpha(user_id))
- if karma:
- karma = karma["karma"]
- await message.reply_text(f"**Total Points**: __{karma}__")
- else:
- karma = 0
- await message.reply_text(f"**Total Points**: __{karma}__")
+ karma = karma["karma"] if karma else 0
+ await message.reply_text(f"**Total Points**: __{karma}__")
@app.on_message(filters.command("karma_toggle") & ~filters.private)
@@ -219,4 +184,4 @@ async def captcha_state(_, message):
await karma_off(chat_id)
await message.reply_text("Disabled Karma System for this chat.")
else:
- await message.reply_text(usage)
\ No newline at end of file
+ await message.reply_text(usage)
diff --git a/misskaty/plugins/misc_tools.py b/misskaty/plugins/misc_tools.py
index c8806c6f..02a3a13f 100644
--- a/misskaty/plugins/misc_tools.py
+++ b/misskaty/plugins/misc_tools.py
@@ -42,6 +42,7 @@ __HELP__ = """
/imdb [query] - Find Movie Details From IMDB.com (Available in English and Indonesia version).
/readqr [reply to photo] - Read QR Code From Photo.
/createqr [text] - Convert Text to QR Code.
+/anime [query] - Search title in myanimelist.
"""
diff --git a/misskaty/plugins/start_help.py b/misskaty/plugins/start_help.py
index 6738760a..e4ac0318 100644
--- a/misskaty/plugins/start_help.py
+++ b/misskaty/plugins/start_help.py
@@ -76,11 +76,7 @@ async def start(_, message, strings):
)
await db.add_chat(message.chat.id, message.chat.title)
- nama = (
- message.from_user.mention
- if message.from_user
- else message.sender_chat.title
- )
+ nama = message.from_user.mention if message.from_user else message.sender_chat.title
return await message.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=strings("start_msg").format(kamuh=nama),
@@ -97,10 +93,7 @@ async def start(_, message, strings):
name = (message.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 kirimPesan(message, text, disable_web_page_preview=True)
elif name == "help":
text, keyb = await help_parser(message.from_user.first_name)
@@ -140,7 +133,6 @@ async def stats_callbacc(_, CallbackQuery):
@ratelimiter
@use_chat_lang()
async def help_command(_, message, strings):
- if not message.from_user: return
if message.chat.type.value != "private":
if not await db.get_chat(message.chat.id):
total = await app.get_chat_members_count(message.chat.id)
@@ -183,10 +175,7 @@ async def help_command(_, message, strings):
if len(message.command) >= 2:
name = (message.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 kirimPesan(message, text, disable_web_page_preview=True)
else:
text, help_keyboard = await help_parser(message.from_user.first_name)
@@ -198,9 +187,7 @@ async def help_command(_, message, strings):
)
else:
text, help_keyboard = await help_parser(message.from_user.first_name)
- await kirimPesan(
- message, text, reply_markup=help_keyboard, disable_web_page_preview=True
- )
+ await kirimPesan(message, text, reply_markup=help_keyboard, disable_web_page_preview=True)
async def help_parser(name, keyboard=None):
@@ -238,9 +225,7 @@ async def help_button(client, query, strings):
await editPesan(
query.message,
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:
@@ -255,9 +240,7 @@ async def help_button(client, query, strings):
await editPesan(
query.message,
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,
)
@@ -266,9 +249,7 @@ async def help_button(client, query, strings):
await editPesan(
query.message,
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,
)
@@ -289,4 +270,4 @@ async def help_button(client, query, strings):
disable_web_page_preview=True,
)
- return await client.answer_callback_query(query.id)
\ No newline at end of file
+ return await client.answer_callback_query(query.id)
diff --git a/misskaty/plugins/sub_extractor.py b/misskaty/plugins/sub_extractor.py
index 1801b811..b63d65dd 100644
--- a/misskaty/plugins/sub_extractor.py
+++ b/misskaty/plugins/sub_extractor.py
@@ -1,6 +1,6 @@
"""
* @author yasir
- * @created 2022-12-01 09:12:27
+ * @created 2022-12-01 09:12:27
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
@@ -21,6 +21,7 @@ from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.errors import capture_err
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.plugins.dev import shell_exec
from misskaty.vars import COMMAND_HANDLER
@@ -63,13 +64,14 @@ def get_subname(lang, url, format):
@app.on_message(filters.command(["ceksub", "extractmedia"], COMMAND_HANDLER))
@ratelimiter
-async def ceksub(_, m):
+@use_chat_lang()
+async def ceksub(_, m, strings):
cmd = m.text.split(" ", 1)
if len(cmd) == 1:
- return await kirimPesan(m, f"Please use command /{m.command[0]} [link] to check subtitles or audio in video file.", quote=True)
+ return await kirimPesan(m, strings("sub_extr_help").format(cmd=m.command[0]), quote=True)
link = cmd[1]
start_time = perf_counter()
- pesan = await kirimPesan(m, "Processing your request..", quote=True)
+ pesan = await kirimPesan(m, strings("progress_str"), quote=True)
try:
res = (await shell_exec(f"ffprobe -loglevel 0 -print_format json -show_format -show_streams {link}"))[0]
details = json.loads(res)
@@ -96,25 +98,26 @@ async def ceksub(_, m):
]
)
end_time = perf_counter()
- timelog = "{:.2f}".format(end_time - start_time) + " second"
- buttons.append([InlineKeyboardButton("❌ Cancel", f"close#{m.from_user.id}")])
+ timelog = "{:.2f}".format(end_time - start_time) + strings("val_sec")
+ buttons.append([InlineKeyboardButton(strings("cancel_btn"), f"close#{m.from_user.id}")])
await editPesan(
pesan,
- f"Press the button below to extract subtitles/audio. Only support direct link at this time.\nProcessed in {timelog}",
+ strings("press_btn_msg").format(timelog=timelog),
reply_markup=InlineKeyboardMarkup(buttons),
)
except:
- await editPesan(pesan, "Failed extract media, make sure your link is not protected by WAF or maybe inaccessible for bot.")
+ await editPesan(pesan, strings("fail_extr_media"))
@app.on_message(filters.command(["converttosrt"], COMMAND_HANDLER))
@capture_err
@ratelimiter
-async def convertsrt(c, m):
+@use_chat_lang()
+async def convertsrt(c, m, strings):
reply = m.reply_to_message
if not reply and reply.document and (reply.document.file_name.endswith(".vtt") or reply.document.file_name.endswith(".ass")):
- return await kirimPesan(m, f"Use command /{m.command[0]} by reply to .ass or .vtt file, to convert subtitle from .ass or .vtt to srt.")
- msg = await kirimPesan(m, "⏳ Converting...", quote=True)
+ return await kirimPesan(m, strings("conv_sub_help").format(cmd=m.command[0]))
+ msg = await kirimPesan(m, strings("convert_str"), quote=True)
dl = await reply.download()
filename = dl.split("/", 3)[3]
LOGGER.info(f"ConvertSub: {filename} by {m.from_user.first_name} [{m.from_user.id}]")
@@ -122,10 +125,10 @@ async def convertsrt(c, m):
c_time = time()
await m.reply_document(
f"{filename}.srt",
- caption=f"{filename}.srt\n\nConverted by @{c.me.username}",
+ caption=strings("capt_conv_sub").format(nf=filename, bot=c.me.username),
thumb="assets/thumb.jpg",
progress=progress_for_pyrogram,
- progress_args=("Uploading files..", msg, c_time),
+ progress_args=(strings("up_str"), msg, c_time),
)
await hapusPesan(msg)
try:
@@ -137,17 +140,18 @@ async def convertsrt(c, m):
@app.on_callback_query(filters.regex(r"^streamextract#"))
@ratelimiter
-async def stream_extract(bot, update):
+@use_chat_lang()
+async def stream_extract(bot, update, strings):
cb_data = update.data
usr = update.message.reply_to_message
if update.from_user.id != usr.from_user.id:
- return await update.answer("⚠️ Access Denied!", True)
+ return await update.answer(strings("unauth_cb"), True)
_, lang, map, codec = cb_data.split("#")
try:
link = update.message.reply_to_message.command[1]
except:
- return await update.answer("⚠️ DONT DELETE YOUR MESSAGE!", True)
- await editPesan(update.message, "⏳ Processing...")
+ return await update.answer(strings("invalid_cb"), True)
+ await editPesan(update.message, strings("progress_str"))
if codec == "aac":
format = "aac"
elif codec == "mp3":
@@ -162,18 +166,18 @@ async def stream_extract(bot, update):
LOGGER.info(f"ExtractSub: {namafile} by {update.from_user.first_name} [{update.from_user.id}]")
(await shell_exec(f"mediaextract -i {link} -map {map} '{namafile}'"))[0]
end_time = perf_counter()
- timelog = "{:.2f}".format(end_time - start_time) + " second"
+ timelog = "{:.2f}".format(end_time - start_time) + strings("val_sec")
c_time = time()
await update.message.reply_document(
namafile,
- caption=f"Filename: {namafile}\n\nExtracted by @{bot.me.username} in {timelog}",
+ caption=strings("capt_extr_sub").format(nf=namafile, bot=bot.me.username, timelog=timelog),
reply_to_message_id=usr.id,
thumb="assets/thumb.jpg",
progress=progress_for_pyrogram,
- progress_args=("Uploading files..", update.message, c_time),
+ progress_args=(strings("up_str"), update.message, c_time),
)
await hapusPesan(update.message)
os.remove(namafile)
except Exception as e:
os.remove(namafile)
- await editPesan(update.message, f"Failed extract sub, Maybe unsupported format..\n\nLink: {link}\nERR: {e}")
+ await editPesan(update.message, strings("fail_extr_sub").format(link=link, e=e))
diff --git a/misskaty/plugins/web_scraper.py b/misskaty/plugins/web_scraper.py
index 656a4497..cffa13ed 100644
--- a/misskaty/plugins/web_scraper.py
+++ b/misskaty/plugins/web_scraper.py
@@ -257,7 +257,7 @@ async def getDataLendrive(msg, kueri, CurrentPage, user, strings):
# MelongMovie GetData
async def getDataMelong(msg, kueri, CurrentPage, user, strings):
if not SCRAP_DICT.get(msg.id):
- data = await http.get(f"https://melongmovie.info/?s={kueri}", headers=headers, follow_redirects=True)
+ data = await http.get(f"http://146.190.193.128/?s={kueri}", headers=headers, follow_redirects=True)
bs4 = BeautifulSoup(data, "lxml")
melongdata = []
for res in bs4.select(".box"):
@@ -781,7 +781,7 @@ async def kusonime_scrap(_, callback_query, strings):
await editPesan(callback_query.message, f"ERROR: {err}", reply_markup=keyboard)
return
data_kuso[link] = {"ph_url": tgh["url"]}
- await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=tgh['url']), reply_markup=keyboard, disable_web_page_preview=False)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=tgh["url"]), reply_markup=keyboard, disable_web_page_preview=False)
# Savefilm21 DDL
diff --git a/misskaty/plugins/ytdl_plugins.py b/misskaty/plugins/ytdl_plugins.py
index 49cd4d0f..92e5fb2c 100644
--- a/misskaty/plugins/ytdl_plugins.py
+++ b/misskaty/plugins/ytdl_plugins.py
@@ -40,7 +40,7 @@ async def ytsearch(_, message, strings):
return await message.reply(strings("no_res").format(kweri=query))
i = search["result"][0]
out = f"{i['title']}\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(
[
[
@@ -184,7 +184,7 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery, strings):
search = await main.VideosSearch(query).next()
i = search["result"][page]
out = f"{i['title']}"
- 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}"),