mirror of
https://github.com/yasirarism/MissKatyPyro.git
synced 2026-01-03 19:14:51 +00:00
MultiLanguage Support [BETA] (#21)
Pushed to public since i dont know when became stable
This commit is contained in:
parent
6ea9bf9d98
commit
3a6c0b424e
72 changed files with 1142 additions and 448 deletions
16
database/locale_db.py
Normal file
16
database/locale_db.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
from pyrogram.enums import ChatType
|
||||
from typing import Iterable
|
||||
from database import dbname
|
||||
|
||||
localesdb = dbname.locale # DB for localization
|
||||
|
||||
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)
|
||||
|
||||
|
||||
async def get_db_lang(chat_id: int, chat_type: str) -> str:
|
||||
ul = await localesdb.find_one({"chat_id": chat_id})
|
||||
return ul["lang"] if ul else {}
|
||||
0
locales/__init__.py
Normal file
0
locales/__init__.py
Normal file
68
locales/en-US/admins.json
Normal file
68
locales/en-US/admins.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"no_admin_error": "You must be an administrator to use this command.",
|
||||
"no_permission_error": "I'm sorry but you don't have the required permissions to run this command. Missing permissions: {permissions}",
|
||||
"private_not_allowed": "This command can't be used in a private chat. If you need any help, please use the <code>/help</code> command.",
|
||||
"purge_no_reply": "Reply to a message to purge from.",
|
||||
"delete_no_reply": "Reply To A Message To Delete It",
|
||||
"pin_no_reply": "Reply to a message to pin/unpin it.",
|
||||
"report_no_reply": "Reply To A Message To Report That User.",
|
||||
"no_delete_perm": "Please give me delete message permission.",
|
||||
"purge_success": "Successfully deleted {del_total} messages..",
|
||||
"user_not_found": "I can't find that user.",
|
||||
"invalid_id_uname": "⚠️ Invalid userid/username",
|
||||
"kick_self_err": "I can't kick myself, i can leave if you want.",
|
||||
"ban_self_err": "I can't ban myself, i can leave if you want.",
|
||||
"report_self_err": "Why are you reporting yourself ?",
|
||||
"demote_self_err": "I can't demote myself.",
|
||||
"warn_self_err": "I can't warn myself.",
|
||||
"mute_self_err": "I can't mute myself.",
|
||||
"kick_sudo_err": "Wow, you wanna kick my owner?",
|
||||
"ban_sudo_err": "Wow, you wanna try ban my owner?",
|
||||
"demote_sudo_err": "Wow, you wanna try demote my owner?",
|
||||
"warn_sudo_err": "Wow, you wanna try give warning to my owner?",
|
||||
"mute_sudo_err": "Wow, you wanna try give mute to my owner?",
|
||||
"kick_admin_err": "Lol, it's crazy if i can kick an admin.",
|
||||
"ban_admin_err": "Lol, it's crazy if i can banned an admin.",
|
||||
"mute_admin_err": "Lol, it's crazy if i can mute an admin.",
|
||||
"warn_admin_err": "Lol, it's crazy if i can warn an admin.",
|
||||
"kick_msg": "**Kicked User:** {mention} [{id}]\n**Kicked By:** {kicker}\n**Reason:** {reasonmsg}",
|
||||
"ban_msg": "**Banned User:** {mention} [{id}]\n**Banned By:** {banner}\n",
|
||||
"unban_msg": "__Banned removed by {mention}__",
|
||||
"no_ban_permission": "Please give me ban permission to ban user in this group.",
|
||||
"no_more_99": "You can't use more than 99",
|
||||
"banned_time": "**Banned For:** {val}\n",
|
||||
"muted_time": "**Muted For:** {val}\n",
|
||||
"banned_reason": "**Reason:** {reas}",
|
||||
"unban_channel_err": "You cannot unban a channel",
|
||||
"give_unban_user": "Provide a username or reply to a user's message to unban.",
|
||||
"unban_success": "Successfully unbanned {umention}!",
|
||||
"give_idban_with_msg_link": "Provide a userid/username along with message link and reason to list-ban",
|
||||
"give_idunban_with_msg_link": "Provide a userid/username along with message link and reason to list-unban",
|
||||
"give_reason_list_ban": "You must provide a reason to list-ban",
|
||||
"Invalid_tg_link": "Invalid message link provided",
|
||||
"multiple_ban_progress": "`Banning User from multiple groups. This may take some time`",
|
||||
"multiple_unban_progress": "`Unbanning User from multiple groups. This may take some time`",
|
||||
"failed_get_uname": "Could not get group usernames",
|
||||
"listban_msg": "**List-Banned User:** {mention}\n**Banned User ID:** `{uid}`\n**Admin:** {frus}\n**Affected chats:** `{ct}`\n**Reason:** {reas}",
|
||||
"listunban_msg": "**List-Unbanned User:** {mention}\n**Unbanned User ID:** `{uid}`\n**Admin:** {frus}\n**Affected chats:** `{ct}`\n**Reason:** {reas}",
|
||||
"promote_self_err": "I can't promote myself.",
|
||||
"no_promote_perm": "Sadly, I don't permission to promote users.",
|
||||
"full_promote": "Fully Promoted {umention}!",
|
||||
"normal_promote": "Promoted {umention}!",
|
||||
"pin_success": "**Pinned [this]({link}) message.**",
|
||||
"unpin_success": "**UnPinned [this]({link}) message.**",
|
||||
"pin_no_perm": "Please give me pin permission to use this command!.",
|
||||
"report_msg": "Reported {user_mention} to admins!",
|
||||
"reported_is_admin": "Do you know that the user you are replying is an admin ?",
|
||||
"user_no_warn": "User {mention} has no warnings.",
|
||||
"ch_warn_msg": "User {mention} has {warns}/3 warnings.",
|
||||
"warn_msg": "**Warned User:** {mention}\n**Warned By:** {warner}\n**Reason:** {reas}\n**Warns:** {twarn}/3",
|
||||
"rmwarn_msg": "Removed warnings of {mention}.",
|
||||
"unwarn_msg": "Removed warnings by {mention}.",
|
||||
"rmmute_msg": "__Mute removed by {mention}__",
|
||||
"unmute_msg": "Unmuted! {umention}",
|
||||
"reply_to_rm_warn": "Reply to a message to remove a user's warnings.",
|
||||
"exceed_warn_msg": "Number of warns of {mention} exceeded, BANNED!",
|
||||
"mute_msg": "**Muted User:** {mention}\n**Muted By:** {muter}\n",
|
||||
"rm_warn_btn": "🚨 Remove Warn 🚨"
|
||||
}
|
||||
5
locales/en-US/chatbot_ai.json
Normal file
5
locales/en-US/chatbot_ai.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"no_question": "Please use command <code>/{cmd} [question]</code> to ask your question.",
|
||||
"find_answers_str": "Wait a moment looking for your answer..",
|
||||
"answers_too_long": "Question for your answer has exceeded TG text limit, check this link to view.\n\n{answerlink}"
|
||||
}
|
||||
3
locales/en-US/fun.json
Normal file
3
locales/en-US/fun.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"result": "🎲 The dice stopped at the number: {number}"
|
||||
}
|
||||
3
locales/en-US/general.json
Normal file
3
locales/en-US/general.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"back_btn": "« Go back"
|
||||
}
|
||||
1
locales/en-US/help_menu.json
Normal file
1
locales/en-US/help_menu.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
5
locales/en-US/lang_setting.json
Normal file
5
locales/en-US/lang_setting.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"language_changed_successfully": "The language has been changed successfully.",
|
||||
"language_changer_chat": "Here you can change the language used for the bot throughout the chat.\nIf your language is not listed here and you would like to contribute, you can open issue in my github repo.",
|
||||
"language_changer_private": "Here you can change the language used for the bot in this private chat.\n\nIf you want to change the language of your group, please run the command <code>/setchatlang</code> on it.\nIf your language is not listed here and you would like to contribute, you can open issue in my github repo."
|
||||
}
|
||||
4
locales/en-US/main.json
Normal file
4
locales/en-US/main.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"language_name": "English",
|
||||
"language_flag": "🇬🇧"
|
||||
}
|
||||
11
locales/en-US/mediainfo.json
Normal file
11
locales/en-US/mediainfo.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"processing_text": "`Processing, total time is based on the size of your files...`",
|
||||
"wait_msg": "`Please wait a moment...`",
|
||||
"err_link": "It looks like the link you sent is invalid, make sure it's a direct link and can be downloaded.",
|
||||
"media_invalid": "Please reply to valid media.",
|
||||
"dl_limit_exceeded": "Sorry, download limited to 2GB to reduce flood. You can convert your files to link.",
|
||||
"dl_args_text": "Trying to download..",
|
||||
"mediainfo_help": "Use the command /{cmd} [link], or reply to telegram media with /{cmd}.",
|
||||
"capt_media": "ℹ️ Your mediainfo results..\n\n**Request By:** {ment}",
|
||||
"viweb": "💬 Open on Web"
|
||||
}
|
||||
6
locales/en-US/ocr.json
Normal file
6
locales/en-US/ocr.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"no_photo": "Reply photo with /{cmd} command to scan text from images.",
|
||||
"read_ocr": "Scanning your images..",
|
||||
"result_ocr": "Hasil OCR:\n<code>{result}</code>",
|
||||
"ocr_helper": "/ocr [reply to photo] - Read Text From Image"
|
||||
}
|
||||
13
locales/en-US/sangmata.json
Normal file
13
locales/en-US/sangmata.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"no_uname": "<code>No Username</code>",
|
||||
"no_last_name": "<code>No Last Name</code>",
|
||||
"uname_change_msg": "✨ Changed username from {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"lastname_change_msg": "✨ Changed last name from {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"firstname_change_msg": "✨ Changed first name from {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"set_sangmata_help": "Use <code>/{cmd} on</code>, to enable sangmata. If you want disable, you can use off parameter.",
|
||||
"sangmata_already_on": "SangMata already enabled in your groups.",
|
||||
"sangmata_enabled": "Sangmata enabled in your groups.",
|
||||
"sangmata_already_off": "SangMata already disabled in your groups.",
|
||||
"sangmata_disabled": "Sangmata disabled in your groups.",
|
||||
"wrong_param": "Unknown parameter, use only on/off parameter."
|
||||
}
|
||||
19
locales/en-US/stickers.json
Normal file
19
locales/en-US/stickers.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"no_anim_stick": "Animated sticker is not supported!",
|
||||
"not_sticker": "This is not a sticker!",
|
||||
"unkang_msg": "Trying to remove from pack..",
|
||||
"unkang_success": "Sticker has been removed from your pack",
|
||||
"unkang_error": "Failed remove sticker from your pack.\n\nERR: {e}",
|
||||
"unkang_help": "Please reply sticker that created by {c} to remove sticker from your pack.",
|
||||
"anon_warn": "You are anon admin, kang stickers in my pm.",
|
||||
"kang_msg": "Trying to steal your sticker...",
|
||||
"stick_no_name": "The sticker has no name.",
|
||||
"kang_help": "Want me to guess the sticker? Please tag a sticker.",
|
||||
"exist_pack": "<code>Using existing sticker pack...</code>",
|
||||
"new_packs": "<b>Creating a new sticker pack...</b>",
|
||||
"please_start_msg": "It looks like you've never interacted with me in private chat, you need to do that first..",
|
||||
"click_me": "Click Me",
|
||||
"pack_full": "Your Sticker Pack is full if your pack is not in v1 Type /kang 1, if it is not in v2 Type /kang 2 and so on.",
|
||||
"viewpack": "👀 View Your Pack",
|
||||
"kang_success": "<b>Sticker successfully stolen!</b>\n<b>Emoji:</b> {emot}"
|
||||
}
|
||||
1
locales/en-US/web_scraper.json
Normal file
1
locales/en-US/web_scraper.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
5
locales/en-US/webss.json
Normal file
5
locales/en-US/webss.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"no_url": "Give A Url To Fetch Screenshot.",
|
||||
"wait_str": "Capturing screenshot...",
|
||||
"ss_failed_str": "Failed To Take Screenshot. {err}"
|
||||
}
|
||||
68
locales/id-ID/admins.json
Normal file
68
locales/id-ID/admins.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"no_admin_error": "Anda harus merupakan administrator untuk menggunakan perintah ini.",
|
||||
"no_permission_error": "Maaf, tapi anda tidak memiliki izin yang diperlukan untuk menjalankan perintah ini. Izin yang hilang: {permissions}",
|
||||
"private_not_allowed": "Perintah ini tidak dapat digunakan dalam obrolan pribadi, Jika anda membutuhkan bantuan, mohon gunakan perintah <code>/help</code>.",
|
||||
"purge_no_reply": "Balas pesan untuk dihapus.",
|
||||
"delete_no_reply": "Balas Pesan Untuk Menghapusnya",
|
||||
"pin_no_reply": "Balas pesan untuk menyematkan/melepas pin.",
|
||||
"report_no_reply": "Balas Pesan Untuk Melaporkan Pengguna Itu.",
|
||||
"no_delete_perm": "Tolong beri saya izin untuk menghapus pesan.",
|
||||
"purge_success": "Berhasil menghapus {del_total} pesan..",
|
||||
"user_not_found": "Saya tidak dapat menemukan pengguna itu.",
|
||||
"invalid_id_uname": "⚠️ ID pengguna/nama pengguna salah",
|
||||
"kick_self_err": "Saya tidak dapat menendang diri sendiri, saya dapat pergi jika Anda mau.",
|
||||
"ban_self_err": "Saya tidak dapat melarang diri saya sendiri, saya dapat pergi jika Anda mau.",
|
||||
"report_self_err": "Mengapa Anda melaporkan diri sendiri?",
|
||||
"demote_self_err": "Saya tidak dapat menurunkan pangkat diri saya sendiri.",
|
||||
"warn_self_err": "Saya tidak dapat memperingatkan diri sendiri.",
|
||||
"mute_self_err": "Saya sendiri tidak dapat membisukan.",
|
||||
"kick_sudo_err": "Wow, Anda ingin menendang pemilik saya?",
|
||||
"ban_sudo_err": "Wow, Anda ingin mencoba mencekal pemilik saya?",
|
||||
"demote_sudo_err": "Wow, Anda ingin mencoba menurunkan pemilik saya?",
|
||||
"warn_sudo_err": "Wow, Anda ingin mencoba memberi peringatan kepada pemilik saya?",
|
||||
"mute_sudo_err": "Wow, Anda ingin mencoba membisukan pemilik saya?",
|
||||
"kick_admin_err": "Hah, sungguh gila jika saya bisa menendang seorang admin.",
|
||||
"ban_admin_err": "Hah, sungguh gila jika saya bisa melarang seorang admin.",
|
||||
"mute_admin_err": "Hah, sungguh gila jika saya bisa membisukan admin.",
|
||||
"warn_admin_err": "Hah, sungguh gila jika saya bisa memperingatkan seorang admin.",
|
||||
"kick_msg": "**Pengguna yang Ditendang:** {mention} [{id}]\n**Ditendang Oleh:** {kicker}\n**Alasan:** {reasonmsg}",
|
||||
"ban_msg": "**Pengguna yang Dilarang:** {mention} [{id}]\n**Dilarang Oleh:** {banner}\n",
|
||||
"unban_msg": "__Banned dihapus oleh {mention}__",
|
||||
"no_ban_permission": "Tolong beri saya izin larangan untuk melarang pengguna di grup ini.",
|
||||
"no_more_99": "Anda tidak dapat menggunakan lebih dari 99",
|
||||
"banned_time": "**Dilarang Untuk:** {val}\n",
|
||||
"muted_time": "**Dimatikan Untuk:** {val}\n",
|
||||
"banned_reason": "**Alasan:** {reas}",
|
||||
"unban_channel_err": "Anda tidak dapat membatalkan pemblokiran saluran",
|
||||
"give_unban_user": "Berikan nama pengguna atau balas pesan pengguna untuk membatalkan larangan.",
|
||||
"unban_success": "Berhasil membatalkan pemblokiran {umention}!",
|
||||
"give_idban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan pelarangan daftar",
|
||||
"give_idunban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan untuk membatalkan larangan",
|
||||
"give_reason_list_ban": "Anda harus memberikan alasan untuk melarang daftar",
|
||||
"Invalid_tg_link": "Tautan pesan yang diberikan tidak valid",
|
||||
"multiple_ban_progress": "`Melarang Pengguna dari banyak grup. Ini mungkin membutuhkan waktu`",
|
||||
"multiple_unban_progress": "`Membatalkan pencekalan Pengguna dari banyak grup. Ini mungkin membutuhkan waktu`",
|
||||
"failed_get_uname": "Tidak dapat memperoleh nama pengguna grup",
|
||||
"listban_msg": "**Pengguna yang Dilarang Daftar:** {mention}\n**ID Pengguna yang Dilarang:** `{uid}`\n**Admin:** {frus}\n**Obrolan yang terpengaruh: ** `{ct}`\n**Alasan:** {reas}",
|
||||
"listunban_msg": "**Pengguna yang Tidak Dilarang Daftar:** {mention}\n**ID Pengguna yang Tidak Dilarang:** `{uid}`\n**Admin:** {frus}\n**Obrolan yang terpengaruh: ** `{ct}`\n**Alasan:** {reas}",
|
||||
"promote_self_err": "Saya tidak dapat mempromosikan diri saya sendiri.",
|
||||
"no_promote_perm": "Sayangnya, saya tidak mengizinkan untuk mempromosikan pengguna.",
|
||||
"full_promote": "Dipromosikan Sepenuhnya {umention}!",
|
||||
"normal_promote": "Dipromosikan {umention}!",
|
||||
"pin_success": "**Pesan [ini]({link}) disematkan.**",
|
||||
"unpin_success": "**Pesan [ini]({link}) yang tidak disematkan.**",
|
||||
"pin_no_perm": "Tolong beri saya izin pin untuk menggunakan perintah ini!.",
|
||||
"report_msg": "Melaporkan {user_mention} ke admin!",
|
||||
"reported_is_admin": "Apakah Anda tahu bahwa pengguna yang Anda balas adalah seorang admin?",
|
||||
"user_no_warn": "Pengguna {mention} tidak memiliki peringatan.",
|
||||
"ch_warn_msg": "User {mention} memiliki {warns}/3 peringatan.",
|
||||
"warn_msg": "**Pengguna yang Diperingatkan:** {mention}\n**Diperingatkan Oleh:** {warner}\n**Alasan:** {reas}\n**Peringatan:** {twarn}/ 3",
|
||||
"rmwarn_msg": "Peringatan {mention} telah dihapus.",
|
||||
"unwarn_msg": "Peringatan dihapus oleh {mention}.",
|
||||
"rmmute_msg": "__Bisukan dihapus oleh {mention}__",
|
||||
"unmute_msg": "Disuarakan! {umention}",
|
||||
"reply_to_rm_warn": "Balas pesan untuk menghapus peringatan pengguna.",
|
||||
"exceed_warn_msg": "Jumlah peringatan dari {mention} terlampaui, DILARANG!",
|
||||
"mute_msg": "**Pengguna yang Dibungkam:** {mention}\n**Dimatikan Oleh:** {muter}\n",
|
||||
"rm_warn_btn": "🚨 Hapus Peringatan 🚨"
|
||||
}
|
||||
5
locales/id-ID/chatbot_ai.json
Normal file
5
locales/id-ID/chatbot_ai.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"no_question": "Harap gunakan perintah <code>/{cmd} [question]</code> untuk mengajukan pertanyaan Anda.",
|
||||
"find_answers_str": "Tunggu sebentar untuk mencari jawaban Anda..",
|
||||
"answers_too_long": "Pertanyaan untuk jawaban Anda telah melampaui batas teks TG, periksa tautan ini untuk melihatnya.\n\n{answerlink}"
|
||||
}
|
||||
3
locales/id-ID/fun.json
Normal file
3
locales/id-ID/fun.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"result": "🎲 Dadu berhenti di angka: {number}"
|
||||
}
|
||||
4
locales/id-ID/general.json
Normal file
4
locales/id-ID/general.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"back_btn": "« Kembali",
|
||||
"no_results": "Tidak ada hasil yang ditemukan."
|
||||
}
|
||||
1
locales/id-ID/help_menu.json
Normal file
1
locales/id-ID/help_menu.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
5
locales/id-ID/lang_setting.json
Normal file
5
locales/id-ID/lang_setting.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"language_changed_successfully": "Bahasa telah berhasil diubah.",
|
||||
"language_changer_chat": "Di sini Anda dapat mengubah bahasa yang digunakan bot selama obrolan.\nJika bahasa Anda tidak ada di sini dan Anda ingin berkontribusi, Anda dapat membuka masalah di github saya. .",
|
||||
"language_changer_private": "Di sini Anda dapat mengubah bahasa yang digunakan oleh bot dalam obrolan pribadi ini.\n\nJika Anda ingin mengubah bahasa grup Anda, buka perintah <code>/setchatlang</code>. \nJika bahasa Anda tidak ada di sini dan Anda ingin berkontribusi, kunjungi repo misskaty."
|
||||
}
|
||||
4
locales/id-ID/main.json
Normal file
4
locales/id-ID/main.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"language_name": "Indonesia",
|
||||
"language_flag": "🇮🇩"
|
||||
}
|
||||
11
locales/id-ID/mediainfo.json
Normal file
11
locales/id-ID/mediainfo.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"processing_text": "`Memproses, total waktu didasarkan pada ukuran file Anda...`",
|
||||
"wait_msg": "`Mohon tunggu sementara...`",
|
||||
"err_link": "Sepertinya tautan yang Anda kirim tidak valid, pastikan tautan langsung dan bisa di unduh.",
|
||||
"media_invalid": "Silakan balas ke media yang valid.",
|
||||
"dl_limit_exceeded": "Maaf, unduh dibatasi hingga 2GB untuk mengurangi banjir. Anda dapat mengonversi berkas Anda menjadi tautan.",
|
||||
"dl_args_text": "Mencoba mengunduh..",
|
||||
"mediainfo_help": "Gunakan perintah /{cmd} [tautan], atau balas telegram media dengan /{cmd}.",
|
||||
"capt_media": "ℹ️ Hasil mediainfo anda..\n\n**Request Oleh:** {ment}",
|
||||
"viewweb": "💬 Buka di Web"
|
||||
}
|
||||
6
locales/id-ID/ocr.json
Normal file
6
locales/id-ID/ocr.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"no_photo": "Balas foto dengan perintah /{cmd} untuk memindai teks dari gambar.",
|
||||
"read_ocr": "Memindai gambar Anda..",
|
||||
"result_ocr": "Hasil OCR:\n<code>{result}</code>",
|
||||
"ocr_helper": "/ocr [balas ke foto] - Baca Teks Dari Gambar"
|
||||
}
|
||||
13
locales/id-ID/sangmata.json
Normal file
13
locales/id-ID/sangmata.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"no_uname": "<code>Tanpa Username</code>",
|
||||
"no_last_name": "<code>Tanpa Nama Belakang</code>",
|
||||
"uname_change_msg": "✨ Mengubah nama depan dari {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"lastname_change_msg": "✨ Mengubah nama belakang dari {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"firstname_change_msg": "✨ Mengubah nama depan dari {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"set_sangmata_help": "Gunakan <code>/{cmd} on</code>, untuk mengaktifkan sangmata. Jika Anda ingin menonaktifkan, Anda dapat menggunakan parameter off.",
|
||||
"sangmata_already_on": "SangMata telah diaktifkan di grup Anda.",
|
||||
"sangmata_enabled": "Sangmata diaktifkan di grup Anda.",
|
||||
"sangmata_already_off": "SangMata telah dinonaktifkan di grup Anda.",
|
||||
"sangmata_disabled": "Sangmata dinonaktifkan di grup Anda.",
|
||||
"wrong_param": "Parameter tidak diketahui, gunakan hanya parameter hidup/mati."
|
||||
}
|
||||
19
locales/id-ID/stickers.json
Normal file
19
locales/id-ID/stickers.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"no_anim_stick": "Stiker animasi tidak didukung!",
|
||||
"not_sticker": "Ini bukan stiker!",
|
||||
"unkang_msg": "Mencoba menghapus dari paket..",
|
||||
"unkang_success": "Stiker telah dihapus dari paket Anda",
|
||||
"unkang_error": "Gagal menghapus stiker dari paket Anda.\n\nERR: {e}",
|
||||
"unkang_help": "Tolong balas stiker yang dibuat oleh {c} untuk menghapus stiker dari paket Anda.",
|
||||
"anon_warn": "Anda adalah admin anon, stiker kang ada di pm saya.",
|
||||
"kang_msg": "Mencoba mencuri stiker Anda...",
|
||||
"stick_no_name": "Stiker tidak memiliki nama.",
|
||||
"kang_help": "Ingin saya menebak stikernya? Harap tandai stiker.",
|
||||
"exist_pack": "<code>Menggunakan paket stiker yang ada...</code>",
|
||||
"new_packs": "<b>Membuat paket stiker baru...</b>",
|
||||
"please_start_msg": "Tampaknya Anda belum pernah berinteraksi dengan saya dalam obrolan pribadi, Anda harus melakukannya dulu..",
|
||||
"click_me": "Klik Saya",
|
||||
"pack_full": "Paket Stiker Anda penuh jika paket Anda tidak dalam Tipe v1 /kang 1, jika tidak dalam Tipe v2 /kang 2 dan seterusnya.",
|
||||
"viewpack": "👀 Lihat Paket Anda",
|
||||
"kang_success": "<b>Stiker berhasil dicuri!</b>\n<b>Emoji:</b> {emot}"
|
||||
}
|
||||
1
locales/id-ID/web_scraper.json
Normal file
1
locales/id-ID/web_scraper.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
5
locales/id-ID/webss.json
Normal file
5
locales/id-ID/webss.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"no_url": "Berikan url untuk mengambil tangkapan layar.",
|
||||
"wait_str": "Mengambil tangkapan layar...",
|
||||
"ss_failed_str": "Gagal Mengambil Tangkapan Layar. ERROR: {err}"
|
||||
}
|
||||
68
locales/id-JW/admins.json
Normal file
68
locales/id-JW/admins.json
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"no_admin_error": "Sampeyan kudu dadi administrator kanggo nggunakake perintah iki.",
|
||||
"no_permission_error": "Ngapunten, nanging sampeyan ora duwe idin sing dibutuhake kanggo nindakake perintah iki. Izin sing ilang: {idin}",
|
||||
"private_not_allowed": "Perintah iki ora bisa digunakake ing obrolan pribadi, Yen sampeyan butuh bantuan, mohon nggunakake perintah <code>/help</code>.",
|
||||
"purge_no_reply": "Bales pesen sing arep dibusak.",
|
||||
"delete_no_reply": "Bales Pesen Kanggo Mbusak",
|
||||
"pin_no_reply": "Bales pesen sing arep disematke/copot.",
|
||||
"report_no_reply": "Bales Pesen Kanggo Nglaporake Panganggo.",
|
||||
"no_delete_perm": "Tulung aku idin mbusak pesen.",
|
||||
"purge_success": "Kasil mbusak {del_total} pesen..",
|
||||
"user_not_found": "Aku ora bisa nemokake panganggo kuwi.",
|
||||
"invalid_id_uname": "⚠️ panganggo/jeneng panganggo ora sah",
|
||||
"kick_self_err": "Aku ora bisa nyepak awakku dhewe, aku bisa lunga yen sampeyan pengin.",
|
||||
"ban_self_err": "Aku ora bisa nglarang aku, aku bisa lunga yen sampeyan pengin.",
|
||||
"report_self_err": "Kenging menapa panjenengan lapor piyambak?",
|
||||
"demote_self_err": "Aku ora bisa mudhun mudhun.",
|
||||
"warn_self_err": "Aku ora bisa ngelekake awakku dhewe.",
|
||||
"mute_self_err": "Aku ora bisa bisu.",
|
||||
"kick_sudo_err": "Wah, kowe arep nyepak juraganku?",
|
||||
"ban_sudo_err": "Wah, sampeyan pengin nyoba nglarang pemilikku?",
|
||||
"demote_sudo_err": "Wah, sampeyan pengin nyoba nurunake pemilikku?",
|
||||
"warn_sudo_err": "Wah, sampeyan pengin nyoba menehi peringatan marang pemilikku?",
|
||||
"mute_sudo_err": "Wah, sampeyan pengin nyoba menehi bisu marang pemilikku?",
|
||||
"kick_admin_err": "Lol, edan yen aku bisa nyepak admin.",
|
||||
"ban_admin_err": "Lol, edan yen aku bisa nglarang admin.",
|
||||
"mute_admin_err": "Lol, edan yen aku bisa bisu admin.",
|
||||
"warn_admin_err": "Lol, edan yen aku bisa ngelingake admin.",
|
||||
"kick_msg": "**Panganggo Ditendhang:** {mention} [{id}]\n**Ditendhang dening:** {kicker}\n**Alasan:** {reasonmsg}",
|
||||
"ban_msg": "**Panganggo sing Dicekal:** {mention} [{id}]\n**Dicekal Dening:** {banner}\n",
|
||||
"unban_msg": "__Dicekal dibusak kanthi {mention}__",
|
||||
"no_ban_permission": "Mangga kula nyuwun idin nglarang panganggo ing grup punika.",
|
||||
"no_more_99": "Sampeyan ora bisa nggunakake luwih saka 99",
|
||||
"banned_time": "**Dicekal Kanggo:** {val}\n",
|
||||
"muted_time": "**Diam Kanggo:** {val}\n",
|
||||
"banned_reason": "**Alesan:** {reas}",
|
||||
"unban_channel_err": "Sampeyan ora bisa mbatalake saluran",
|
||||
"give_unban_user": "Nyedhiyani jeneng panganggo utawa mbales pesen panganggo kanggo mbatalake larangan.",
|
||||
"unban_success": "Kasil mbatalake {umention}!",
|
||||
"give_idban_with_msg_link": "Nyedhiyakake id panganggo/jeneng panganggo bebarengan karo pranala pesen lan alasan kanggo larangan daftar",
|
||||
"give_idunban_with_msg_link": "Nyedhiyani id panganggo/jeneng panganggo bebarengan karo pranala pesen lan alasan kanggo daftar-unban",
|
||||
"give_reason_list_ban": "Sampeyan kudu menehi alesan kanggo nglarang daftar",
|
||||
"Invalid_tg_link": "Link pesen ora sah diwenehake",
|
||||
"multiple_ban_progress": "`Nglarang Panganggo saka macem-macem grup. Iki mbutuhake sawetara wektu`",
|
||||
"multiple_unban_progress": "`Mbusak Larangan Panganggo saka pirang-pirang grup. Iki mbutuhake sawetara wektu`",
|
||||
"failed_get_uname": "Ora bisa njupuk jeneng panganggo grup",
|
||||
"listban_msg": "**Panganggo sing Dilarang Dhaptar:** {mention}\n**ID Panganggo sing Dicekal:** `{uid}`\n**Admin:** {frus}\n**Obrolan sing kena pengaruh: ** `{ct}`\n**Alasan:** {reas}",
|
||||
"listunban_msg": "**Daftar Panganggo sing Ora Dilarang:** {mention}\n**ID Panganggo sing Ora Dilarang:** `{uid}`\n**Admin:** {frus}\n**Obrolan sing kena pengaruh: ** `{ct}`\n**Alasan:** {reas}",
|
||||
"promote_self_err": "Aku ora bisa promosi dhewe.",
|
||||
"no_promote_perm": "Sedhih, aku ora ijin kanggo promosi pangguna.",
|
||||
"full_promote": "{umention} dipromosekake kanthi lengkap!",
|
||||
"normal_promote": "Dipromosikan {umention}!",
|
||||
"pin_success": "**Semat [iki]({link}) pesen.**",
|
||||
"unpin_success": "**Pesen [iki] ({pranala}) ora disemat.**",
|
||||
"pin_no_perm": "Tulung wenehi pin idin kanggo nggunakake printah iki!.",
|
||||
"report_msg": "Kacarita {user_mention} menyang admin!",
|
||||
"reported_is_admin": "Apa sampeyan ngerti yen pangguna sing sampeyan bales iku admin?",
|
||||
"user_no_warn": "Panganggo {mention} ora ana bebaya.",
|
||||
"ch_warn_msg": "{mention} duwe {warning}/3 bebaya.",
|
||||
"warn_msg": "**Panganggo sing Dielingake:** {mention}\n**Dielingake Dening:** {warner}\n**Alesan:** {reas}\n**Ngelingake:** {twarn}/ 3",
|
||||
"rmwarn_msg": "Pènget saka {mention} wis dibusak.",
|
||||
"unwarn_msg": "Pènget sing dibusak kanthi {mention}.",
|
||||
"rmmute_msg": "__Bisu dibusak kanthi {mention}__",
|
||||
"unmute_msg": "Ora bisu! {umention}",
|
||||
"reply_to_rm_warn": "Bales pesen kanggo mbusak bebaya pangguna.",
|
||||
"exceed_warn_msg": "Jumlah peringatan babagan {mention} ngluwihi, DIBRANG!",
|
||||
"mute_msg": "**Panganggo Bisu:** {mention}\n**Dibunyikan Dening:** {muter}\n",
|
||||
"rm_warn_btn": "🚨 Copot Warn 🚨"
|
||||
}
|
||||
5
locales/id-JW/chatbot_ai.json
Normal file
5
locales/id-JW/chatbot_ai.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"no_question": "Tulung gunakake printah <code>/{cmd} [pitakon]</code> kanggo takon.",
|
||||
"find_answers_str": "Ngenteni sedhela goleki jawabanmu..",
|
||||
"answers_too_long": "Pitakonan kanggo jawaban sampeyan wis ngluwihi wates teks TG, priksa pranala iki kanggo ndeleng.\n\n{answerlink}"
|
||||
}
|
||||
3
locales/id-JW/fun.json
Normal file
3
locales/id-JW/fun.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"result": "🎲 Dadu mandheg ing nomer: {number}"
|
||||
}
|
||||
4
locales/id-JW/general.json
Normal file
4
locales/id-JW/general.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"back_btn": "« Balik Maneh",
|
||||
"no_results": "Ora ana asil sing ditemokake."
|
||||
}
|
||||
1
locales/id-JW/help_menu.json
Normal file
1
locales/id-JW/help_menu.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
5
locales/id-JW/lang_setting.json
Normal file
5
locales/id-JW/lang_setting.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"language_changed_successfully": "Basa wis kasil diganti.",
|
||||
"language_changer_chat": "Ing kene sampeyan bisa ngganti basa sing digunakake kanggo bot sajrone obrolan.\nYen basa sampeyan ora ana ing kene lan sampeyan pengin nyumbang, sampeyan bisa mbukak masalah ing githubku. .",
|
||||
"language_changer_private": "Ing kene sampeyan bisa ngganti basa sing digunakake kanggo bot ing obrolan pribadi iki.\n\nYen sampeyan pengin ngganti basa grup sampeyan, bukak printah <code>/setchatlang</code>. \nYen basa sampeyan ora ana ing kene lan sampeyan pengin nyumbang, bukak repo misskaty."
|
||||
}
|
||||
4
locales/id-JW/main.json
Normal file
4
locales/id-JW/main.json
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"language_name": "Jawa",
|
||||
"language_flag": "💫"
|
||||
}
|
||||
11
locales/id-JW/mediainfo.json
Normal file
11
locales/id-JW/mediainfo.json
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"processing_text": "`Pengolahan, wektu total adhedhasar ukuran berkas panjenengan...`",
|
||||
"wait_msg": "`Mohon tunggu sejenak...`",
|
||||
"err_link": "Kayak'e pranala sing dikirim ora valid, priksa link langsung lan bisa diundhuh.",
|
||||
"media_invalid": "Mangga mbales media sing bener.",
|
||||
"dl_limit_exceeded": "Nuwun sewu, download diwatesi 2GB kanggo nyuda banjir. Sampeyan bisa ngowahi file dadi link.",
|
||||
"dl_args_text": "Nyoba ngundhuh..",
|
||||
"mediainfo_help": "Gunakake printah /{cmd} [link], utawa bales media telegram nganggo /{cmd}.",
|
||||
"capt_media": "ℹ️ Hasil mediainfo anda..\n\n**Panjalukan Oleh:** {ment}",
|
||||
"viweb": "💬 Bukak Web"
|
||||
}
|
||||
6
locales/id-JW/ocr.json
Normal file
6
locales/id-JW/ocr.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"no_photo": "Bales foto nganggo printah /{cmd} kanggo mindhai teks saka gambar.",
|
||||
"read_ocr": "Mindai gambar sampeyan..",
|
||||
"result_ocr": "Hasil OCR:\n<kode>{result}</code>",
|
||||
"ocr_helper": "/ocr [reply to photo] - Waca Teks Saka Gambar"
|
||||
}
|
||||
13
locales/id-JW/sangmata.json
Normal file
13
locales/id-JW/sangmata.json
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"no_uname": "<code>Ora Jeneng Panganggo</code>",
|
||||
"no_last_name": "<kode>Ora Ana Jeneng mburi</code>",
|
||||
"uname_change_msg": "✨ Jeneng pangguna diganti saka {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"lastname_change_msg": "✨ Ganti jeneng mburi saka {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"firstname_change_msg": "✨ Ganti jeneng ngarep saka {bef} ➡️ <code>{aft}</code>.\n",
|
||||
"set_sangmata_help": "Gunakake <code>/{cmd} on</code>, kanggo ngaktifake sangmata. Yen sampeyan pengin mateni, sampeyan bisa nggunakake parameter mati.",
|
||||
"sangmata_already_on": "SangMata wis diaktifake ing grup sampeyan.",
|
||||
"sangmata_enabled": "Sangmata diaktifake ing grup sampeyan.",
|
||||
"sangmata_already_off": "SangMata wis dipateni ing grup sampeyan.",
|
||||
"sangmata_disabled": "Sangmata dipateni ing grup sampeyan.",
|
||||
"wrong_param": "Parameter sing ora dingerteni, gunakake mung parameter aktif/mati."
|
||||
}
|
||||
19
locales/id-JW/stickers.json
Normal file
19
locales/id-JW/stickers.json
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"no_anim_stick": "Stiker animasi ora didhukung!",
|
||||
"not_sticker": "Iki dudu stiker!",
|
||||
"unkang_msg": "Nyoba nyopot saka pack..",
|
||||
"unkang_success": "Stiker wis dibusak saka pack panjenengan",
|
||||
"unkang_error": "Gagal mbusak stiker saka paket sampeyan.\n\nERR: {e}",
|
||||
"unkang_help": "Mangga wangsulana stiker sing digawe {c} kanggo mbusak stiker saka paket sampeyan.",
|
||||
"anon_warn": "Sampeyan anon admin, kang stiker ing pmku.",
|
||||
"kang_msg": "Nyolong stiker sampeyan...",
|
||||
"stick_no_name": "Stiker ora ana jeneng.",
|
||||
"kang_help": "Arep tak tebak stikere? Mangga tag stiker.",
|
||||
"exist_pack": "<code>Nganggo paket stiker sing ana...</code>",
|
||||
"new_packs": "<b>Nggawe pak stiker anyar...</b>",
|
||||
"please_start_msg": "Koyone sampeyan ora tau sesambungan karo aku ing obrolan pribadi, sampeyan kudu nglakoni dhisik..",
|
||||
"click_me": "Klik Aku",
|
||||
"pack_full": "Paket Stiker sampeyan kebak yen paket sampeyan ora ana ing tipe v1 /kang 1, yen ora ana ing Tipe v2 /kang 2 lan sapiturute.",
|
||||
"viewpack": "👀 Deleng Paket Sampeyan",
|
||||
"kang_success": "<b>Stiker kasil dicolong!</b>\n<b>Emoji:</b> {emot}"
|
||||
}
|
||||
1
locales/id-JW/web_scraper.json
Normal file
1
locales/id-JW/web_scraper.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{}
|
||||
5
locales/id-JW/webss.json
Normal file
5
locales/id-JW/webss.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"no_url": "Wenehana url kanggo njupuk screenshot.",
|
||||
"wait_str": "Lagi njupuk gambar layar...",
|
||||
"ss_failed_str": "Gagal njupuk gambar. ERROR: {err}"
|
||||
}
|
||||
|
|
@ -10,7 +10,7 @@ from pyrogram import Client
|
|||
|
||||
from misskaty.vars import API_HASH, API_ID, BOT_TOKEN, DATABASE_URI, USER_SESSION, TZ
|
||||
|
||||
basicConfig(filename="MissKatyLogs.txt", format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", level=INFO)
|
||||
basicConfig(filename="MissKatyLogs.txt", format="%(asctime)s - %(name)s.%(funcName)s - %(levelname)s - %(message)s", level=INFO)
|
||||
|
||||
logger = getLogger()
|
||||
# handler logging dengan batasan 100 baris
|
||||
|
|
@ -41,15 +41,9 @@ user = Client(
|
|||
|
||||
pymonclient = MongoClient(DATABASE_URI)
|
||||
|
||||
jobstores = {
|
||||
'default': MongoDBJobStore(
|
||||
client=pymonclient,
|
||||
database="MissKatyDB",
|
||||
collection='nightmode')}
|
||||
jobstores = {"default": MongoDBJobStore(client=pymonclient, database="MissKatyDB", collection="nightmode")}
|
||||
|
||||
scheduler = AsyncIOScheduler(
|
||||
jobstores=jobstores,
|
||||
timezone=TZ)
|
||||
scheduler = AsyncIOScheduler(jobstores=jobstores, timezone=TZ)
|
||||
|
||||
app.start()
|
||||
user.start()
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ async def start(_, message):
|
|||
)
|
||||
return await message.reply_photo(
|
||||
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
|
||||
caption=f"Hi {nama}, Pm Me For More Info About Me.",
|
||||
caption=f"Hi {nama}, PM me to know about all my features. You can change bot language in bot using <code>/setlang</code> command but it's in beta stage.",
|
||||
reply_markup=keyboard,
|
||||
)
|
||||
if not await db.is_user_exist(message.from_user.id):
|
||||
|
|
@ -273,7 +273,7 @@ async def help_parser(name, keyboard=None):
|
|||
keyboard = InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help"))
|
||||
return (
|
||||
"""Hello {first_name}, My name is {bot_name}.
|
||||
I'm a bot with some useful features.
|
||||
I'm a bot with some useful features. You can change language bot using <code>/setlang</code> command, but it's in beta stage.
|
||||
You can choose an option below, by clicking a button.
|
||||
|
||||
If you want give coffee to my owner you can send /donate command for more info.
|
||||
|
|
@ -302,6 +302,7 @@ You can choose an option below, by clicking a button below.
|
|||
General command are:
|
||||
- /start: Start the bot
|
||||
- /help: Give this message
|
||||
- /setlang: Change bot language [BETA]
|
||||
"""
|
||||
if mod_match:
|
||||
module = mod_match[1].replace(" ", "_")
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
from functools import wraps
|
||||
from time import time
|
||||
from functools import partial, wraps
|
||||
from typing import Union, Optional
|
||||
|
||||
from traceback import format_exc as err
|
||||
|
||||
from pyrogram import enums
|
||||
from pyrogram import enums, Client
|
||||
from pyrogram.errors.exceptions.forbidden_403 import ChatWriteForbidden
|
||||
from pyrogram.types import Message
|
||||
from ...helper.localization import default_language, get_lang, get_locale_string, langdict
|
||||
from pyrogram.types import Message, CallbackQuery
|
||||
|
||||
from misskaty import app
|
||||
from misskaty.vars import SUDO
|
||||
|
|
@ -37,6 +40,43 @@ async def member_permissions(chat_id: int, user_id: int):
|
|||
return perms
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
admins_in_chat = {}
|
||||
|
||||
|
||||
|
|
@ -107,3 +147,44 @@ def adminsOnly(permission):
|
|||
return subFunc2
|
||||
|
||||
return subFunc
|
||||
|
||||
|
||||
def require_admin(
|
||||
permissions: Union[list, str] = None,
|
||||
allow_in_private: bool = False,
|
||||
complain_missing_perms: bool = True,
|
||||
):
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
async def wrapper(client: Client, message: Union[CallbackQuery, Message], *args, **kwargs):
|
||||
lang = await get_lang(message)
|
||||
strings = partial(
|
||||
get_locale_string,
|
||||
langdict[lang].get("admins", langdict[default_language]["admins"]),
|
||||
lang,
|
||||
"admins",
|
||||
)
|
||||
|
||||
if isinstance(message, CallbackQuery):
|
||||
sender = partial(message.answer, show_alert=True)
|
||||
msg = message.message
|
||||
elif isinstance(message, Message):
|
||||
sender = message.reply_text
|
||||
msg = message
|
||||
else:
|
||||
raise NotImplementedError(f"require_admin can't process updates with the type '{message.__name__}' yet.")
|
||||
|
||||
# We don't actually check private and channel chats.
|
||||
if msg.chat.type == enums.ChatType.PRIVATE:
|
||||
if allow_in_private:
|
||||
return await func(client, message, *args, *kwargs)
|
||||
return await sender(strings("private_not_allowed"))
|
||||
if msg.chat.type == enums.ChatType.CHANNEL:
|
||||
return await func(client, message, *args, *kwargs)
|
||||
has_perms = await check_perms(message, permissions, complain_missing_perms, strings)
|
||||
if has_perms:
|
||||
return await func(client, message, *args, *kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ ratelimit = RateLimiter()
|
|||
warned_users = TTLCache(maxsize=128, ttl=60)
|
||||
warning_message = "Spam detected! ignoring your all requests for few minutes."
|
||||
|
||||
|
||||
def ratelimiter(func: Callable) -> Callable:
|
||||
"""
|
||||
Restricts user's from spamming commands or pressing buttons multiple times
|
||||
|
|
@ -22,7 +23,6 @@ def ratelimiter(func: Callable) -> Callable:
|
|||
is_limited = await ratelimit.acquire(userid)
|
||||
|
||||
if is_limited and userid not in warned_users:
|
||||
|
||||
if isinstance(update, Message):
|
||||
await update.reply_text(warning_message)
|
||||
warned_users[userid] = 1
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
from typing import Union
|
||||
|
||||
from pyrate_limiter import (BucketFullException, Duration, Limiter,
|
||||
MemoryListBucket, RequestRate)
|
||||
from pyrate_limiter import BucketFullException, Duration, Limiter, MemoryListBucket, RequestRate
|
||||
|
||||
|
||||
class RateLimiter:
|
||||
|
|
@ -12,7 +11,6 @@ class RateLimiter:
|
|||
"""
|
||||
|
||||
def __init__(self) -> None:
|
||||
|
||||
# 2 requests per seconds
|
||||
self.second_rate = RequestRate(2, Duration.SECOND)
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ def get_readable_time(seconds: int) -> str:
|
|||
|
||||
def get_readable_bitrate(bitrate_kbps):
|
||||
if bitrate_kbps > 10000:
|
||||
bitrate = str(round(bitrate_kbps / 1000, 2)) + ' ' + 'Mb/s'
|
||||
bitrate = str(round(bitrate_kbps / 1000, 2)) + " " + "Mb/s"
|
||||
else:
|
||||
bitrate = str(round(bitrate_kbps, 2)) + ' ' + 'kb/s'
|
||||
bitrate = str(round(bitrate_kbps, 2)) + " " + "kb/s"
|
||||
|
||||
return bitrate
|
||||
|
||||
|
|
|
|||
124
misskaty/helper/localization.py
Normal file
124
misskaty/helper/localization.py
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
import inspect
|
||||
import json
|
||||
import os.path
|
||||
from functools import partial, wraps
|
||||
from glob import glob
|
||||
from typing import Dict, List
|
||||
|
||||
from pyrogram.enums import ChatType
|
||||
from pyrogram.types import CallbackQuery, InlineQuery, Message
|
||||
|
||||
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"
|
||||
|
||||
|
||||
def cache_localizations(files: List[str]) -> Dict[str, Dict[str, Dict[str, str]]]:
|
||||
ldict = {lang: {} for lang in enabled_locales}
|
||||
for file in files:
|
||||
_, lname, pname = file.split(os.path.sep)
|
||||
pname = pname.split(".")[0]
|
||||
dic = json.load(open(file, encoding="utf-8"))
|
||||
dic.update(ldict[lname].get(pname, {}))
|
||||
ldict[lname][pname] = dic
|
||||
return ldict
|
||||
|
||||
|
||||
jsons: List[str] = []
|
||||
|
||||
for locale in enabled_locales:
|
||||
jsons += glob(os.path.join("locales", locale, "*.json"))
|
||||
|
||||
langdict = cache_localizations(jsons)
|
||||
|
||||
|
||||
def get_locale_string(dic: dict, language: str, default_context: str, key: str, context: str = None) -> str:
|
||||
if context:
|
||||
default_context = context
|
||||
dic = langdict[language].get(context, langdict[default_language][context])
|
||||
res: str = dic.get(key) or langdict[default_language][default_context].get(key) or key
|
||||
return res
|
||||
|
||||
|
||||
async def get_lang(message) -> str:
|
||||
if isinstance(message, CallbackQuery):
|
||||
chat = message.message.chat
|
||||
elif isinstance(message, Message):
|
||||
chat = message.chat
|
||||
elif isinstance(message, InlineQuery):
|
||||
chat, chat.type = message.from_user, ChatType.PRIVATE
|
||||
else:
|
||||
raise TypeError(f"Update type '{message.__name__}' is not supported.")
|
||||
|
||||
lang = await get_db_lang(chat.id, chat.type)
|
||||
|
||||
if chat.type == ChatType.PRIVATE:
|
||||
lang = lang or message.from_user.language_code or default_language
|
||||
else:
|
||||
lang = lang or default_language
|
||||
# User has a language_code without hyphen
|
||||
if len(lang.split("-")) == 1:
|
||||
# Try to find a language that starts with the provided language_code
|
||||
for locale_ in enabled_locales:
|
||||
if locale_.startswith(lang):
|
||||
lang = locale_
|
||||
elif lang.split("-")[1].islower():
|
||||
lang = lang.split("-")
|
||||
lang[1] = lang[1].upper()
|
||||
lang = "-".join(lang)
|
||||
return lang if lang in enabled_locales else default_language
|
||||
|
||||
|
||||
def use_chat_lang(context: str = None):
|
||||
if not context:
|
||||
cwd = os.getcwd()
|
||||
frame = inspect.stack()[1]
|
||||
|
||||
fname = frame.filename
|
||||
|
||||
if fname.startswith(cwd):
|
||||
fname = fname[len(cwd) + 1 :]
|
||||
context = fname.split(os.path.sep)[2].split(".")[0]
|
||||
|
||||
def decorator(func):
|
||||
@wraps(func)
|
||||
async def wrapper(client, message):
|
||||
lang = await get_lang(message)
|
||||
|
||||
dic = langdict.get(lang, langdict[default_language])
|
||||
|
||||
lfunc = partial(get_locale_string, dic.get(context, {}), lang, context)
|
||||
return await func(client, message, lfunc)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
|
@ -168,37 +168,25 @@ def html_builder(title: str, text: str) -> str:
|
|||
if "Text #" in line:
|
||||
if bool(re.search("Text #1$", line)):
|
||||
subtitle_count = len(re.findall("Text #", text))
|
||||
html_msg += icon.format(
|
||||
icon_url="https://te.legra.ph/file/9d4a676445544d0f2d6db.png"
|
||||
)
|
||||
html_msg += subheading.format(
|
||||
content=f"Subtitles ({subtitle_count} subtitle)"
|
||||
)
|
||||
html_msg += icon.format(icon_url="https://te.legra.ph/file/9d4a676445544d0f2d6db.png")
|
||||
html_msg += subheading.format(content=f"Subtitles ({subtitle_count} subtitle)")
|
||||
html_msg += "<span style='padding: 10px 0vw;' class='subtitle'>"
|
||||
|
||||
elif "General" in line:
|
||||
html_msg += icon.format(
|
||||
icon_url="https://te.legra.ph/file/638fb0416f2600e7c5aa3.png"
|
||||
)
|
||||
html_msg += icon.format(icon_url="https://te.legra.ph/file/638fb0416f2600e7c5aa3.png")
|
||||
html_msg += subheading.format(content="General")
|
||||
|
||||
elif "Video" in line:
|
||||
html_msg += icon.format(
|
||||
icon_url="https://te.legra.ph/file/fbc30d71cf71c9a54e59d.png"
|
||||
)
|
||||
html_msg += icon.format(icon_url="https://te.legra.ph/file/fbc30d71cf71c9a54e59d.png")
|
||||
html_msg += subheading.format(content="Video")
|
||||
|
||||
elif "Audio" in line:
|
||||
html_msg += icon.format(
|
||||
icon_url="https://te.legra.ph/file/a3c431be457fedbae2286.png"
|
||||
)
|
||||
html_msg += icon.format(icon_url="https://te.legra.ph/file/a3c431be457fedbae2286.png")
|
||||
html_msg += subheading.format(content=f"{line.strip()}")
|
||||
|
||||
elif "Menu" in line:
|
||||
html_msg += "</span>"
|
||||
html_msg += icon.format(
|
||||
icon_url="https://te.legra.ph/file/3023b0c2bc202ec9d6d0d.png"
|
||||
)
|
||||
html_msg += icon.format(icon_url="https://te.legra.ph/file/3023b0c2bc202ec9d6d0d.png")
|
||||
html_msg += subheading.format(content="Chapters")
|
||||
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,22 +1,23 @@
|
|||
import cfscrape
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
|
||||
async def down_page(url):
|
||||
f = cfscrape.create_scraper()
|
||||
resp = f.get(url).text
|
||||
soup = BeautifulSoup(resp, 'lxml')
|
||||
maindiv = soup.body.find('div', class_='subtitle').find('div', class_='top left')
|
||||
title = maindiv.find('div', class_='header').h1.span.text.strip()
|
||||
soup = BeautifulSoup(resp, "lxml")
|
||||
maindiv = soup.body.find("div", class_="subtitle").find("div", class_="top left")
|
||||
title = maindiv.find("div", class_="header").h1.span.text.strip()
|
||||
try:
|
||||
imdb = maindiv.find('div', class_='header').h1.a['href']
|
||||
imdb = maindiv.find("div", class_="header").h1.a["href"]
|
||||
except TypeError:
|
||||
imdb = ""
|
||||
try:
|
||||
poster = maindiv.find('div', class_='poster').a['href']
|
||||
poster = maindiv.find("div", class_="poster").a["href"]
|
||||
except:
|
||||
poster = ""
|
||||
try:
|
||||
author_name = maindiv.find('div', class_='header').ul.find('li', class_='author').a.text.strip()
|
||||
author_name = maindiv.find("div", class_="header").ul.find("li", class_="author").a.text.strip()
|
||||
author_link = f"https://subscene.com{maindiv.find('div', class_='header').ul.find('li', class_='author').a['href']}"
|
||||
except:
|
||||
author_link = ""
|
||||
|
|
@ -25,19 +26,17 @@ async def down_page(url):
|
|||
download_url = f"https://subscene.com{maindiv.find('div', class_='header').ul.find('li', class_='clearfix').find('div', class_='download').a['href']}"
|
||||
|
||||
try:
|
||||
comments = maindiv.find('div', class_='header').ul.find('li', class_='comment-wrapper').find('div',
|
||||
class_='comment').text
|
||||
comments = maindiv.find("div", class_="header").ul.find("li", class_="comment-wrapper").find("div", class_="comment").text
|
||||
except:
|
||||
comments = ""
|
||||
try:
|
||||
release = maindiv.find('div', class_='header').ul.find('li', class_='release').find_all('div')
|
||||
release = maindiv.find("div", class_="header").ul.find("li", class_="release").find_all("div")
|
||||
releases = ""
|
||||
for i in range(2):
|
||||
r = release[i].text.strip()
|
||||
releases = releases + f"\n{r}"
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
releases = ""
|
||||
|
||||
response = {"title": title, "imdb": imdb, "poster": poster, "author_name": author_name,
|
||||
"author_url": author_link, "download_url": download_url, "comments": comments, "releases": releases}
|
||||
response = {"title": title, "imdb": imdb, "poster": poster, "author_name": author_name, "author_url": author_link, "download_url": download_url, "comments": comments, "releases": releases}
|
||||
return response
|
||||
|
|
@ -140,6 +140,4 @@ async def search_jw(movie_name: str, locale: str):
|
|||
return m_t_
|
||||
|
||||
|
||||
SUPPORTED_URL_REGEX = {
|
||||
r"(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])": "ddl"
|
||||
}
|
||||
SUPPORTED_URL_REGEX = {r"(http|ftp|https):\/\/([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:\/~+#-]*[\w@?^=%&\/~+#-])": "ddl"}
|
||||
|
|
|
|||
|
|
@ -13,12 +13,14 @@ from misskaty.core.decorator.errors import capture_err
|
|||
from misskaty.core.decorator.permissions import (
|
||||
admins_in_chat,
|
||||
adminsOnly,
|
||||
require_admin,
|
||||
list_admins,
|
||||
member_permissions,
|
||||
)
|
||||
from misskaty.core.decorator.ratelimiter import ratelimiter
|
||||
from misskaty.core.keyboard import ikb
|
||||
from misskaty.core.message_utils import kirimPesan
|
||||
from misskaty.helper.localization import use_chat_lang
|
||||
from misskaty.helper.functions import (
|
||||
extract_user,
|
||||
extract_user_and_reason,
|
||||
|
|
@ -74,9 +76,10 @@ async def admin_cache_func(_, cmu):
|
|||
|
||||
# Purge CMD
|
||||
@app.on_message(filters.command("purge", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_delete_messages")
|
||||
@require_admin(permissions=["can_delete_messages"], allow_in_private=True)
|
||||
@ratelimiter
|
||||
async def purge(_, message):
|
||||
@use_chat_lang()
|
||||
async def purge(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
try:
|
||||
|
|
@ -84,7 +87,7 @@ async def purge(_, message):
|
|||
await message.delete()
|
||||
|
||||
if not repliedmsg:
|
||||
return await message.reply_text("Reply to a message to purge from.")
|
||||
return await message.reply_text(strings("purge_no_reply"))
|
||||
|
||||
cmd = message.command
|
||||
if len(cmd) > 1 and cmd[1].isdigit():
|
||||
|
|
@ -122,32 +125,30 @@ async def purge(_, message):
|
|||
revoke=True,
|
||||
)
|
||||
del_total += len(message_ids)
|
||||
await kirimPesan(message, f"Successfully deleted {del_total} messages..")
|
||||
await kirimPesan(message, strings("purge_success").format(del_total=del_total))
|
||||
except Exception as err:
|
||||
await kirimPesan(message, f"ERR: {err}")
|
||||
await kirimPesan(message, f"ERROR: {err}")
|
||||
|
||||
|
||||
# Kick members
|
||||
@app.on_message(filters.command(["kick", "dkick"], COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def kickFunc(client, message):
|
||||
@use_chat_lang()
|
||||
async def kickFunc(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
user_id, reason = await extract_user_and_reason(message)
|
||||
if not user_id:
|
||||
return await kirimPesan(message, "I can't find that user.")
|
||||
return await kirimPesan(message, strings("user_not_found"))
|
||||
if user_id == client.me.id:
|
||||
return await kirimPesan(message, "I can't kick myself, i can leave if you want.")
|
||||
return await kirimPesan(message, strings("kick_self_err"))
|
||||
if user_id in SUDO:
|
||||
return await kirimPesan(message, "Wow, you wanna kick my owner?")
|
||||
return await kirimPesan(message, strings("kick_sudo_err"))
|
||||
if user_id in (await list_admins(message.chat.id)):
|
||||
return await kirimPesan(message, "Lol, it's crazy if i can kick an admin.")
|
||||
return await kirimPesan(message, strings("kick_admin_err"))
|
||||
user = await app.get_users(user_id)
|
||||
msg = f"""
|
||||
**Kicked User:** {user.mention} [{user.id}]
|
||||
**Kicked By:** {message.from_user.mention if message.from_user else 'Anon'}
|
||||
**Reason:** {reason or '-'}"""
|
||||
msg = strings("kick_msg").format(mention=user.mention, id=user.id, kicker=message.from_user.mention if message.from_user else "Anon Admin", reasonmsg=reason or "-")
|
||||
if message.command[0][0] == "d":
|
||||
await message.reply_to_message.delete()
|
||||
try:
|
||||
|
|
@ -156,33 +157,34 @@ async def kickFunc(client, message):
|
|||
await asyncio.sleep(1)
|
||||
await message.chat.unban_member(user_id)
|
||||
except ChatAdminRequired:
|
||||
await kirimPesan(message, "Please give me ban permission to ban user in this group.")
|
||||
await kirimPesan(message, strings("no_ban_permission"))
|
||||
|
||||
|
||||
# Ban/DBan/TBan User
|
||||
@app.on_message(filters.command(["ban", "dban", "tban"], COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def banFunc(client, message):
|
||||
@use_chat_lang()
|
||||
async def banFunc(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
user_id, reason = await extract_user_and_reason(message, sender_chat=True)
|
||||
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
if user_id == client.me.id:
|
||||
return await message.reply_text("I can't ban myself, i can leave if you want.")
|
||||
return await message.reply_text(strings("ban_self_err"))
|
||||
if user_id in SUDO:
|
||||
return await message.reply_text("You Wanna Ban The Elevated One?, RECONSIDER!")
|
||||
return await message.reply_text(strings("ban_sudo_err"))
|
||||
if user_id in (await list_admins(message.chat.id)):
|
||||
return await message.reply_text("I can't ban an admin, You know the rules, so do i.")
|
||||
return await message.reply_text(strings("ban_admin_err"))
|
||||
|
||||
try:
|
||||
mention = (await app.get_users(user_id)).mention
|
||||
except IndexError:
|
||||
mention = message.reply_to_message.sender_chat.title if message.reply_to_message else "Anon"
|
||||
|
||||
msg = f"**Banned User:** {mention}\n" f"**Banned By:** {message.from_user.mention if message.from_user else 'Anon'}\n"
|
||||
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":
|
||||
|
|
@ -190,20 +192,20 @@ async def banFunc(client, message):
|
|||
time_value = split[0]
|
||||
temp_reason = split[1] if len(split) > 1 else ""
|
||||
temp_ban = await time_converter(message, time_value)
|
||||
msg += f"**Banned For:** {time_value}\n"
|
||||
msg += strings("banner_time").format(val=time_value)
|
||||
if temp_reason:
|
||||
msg += f"**Reason:** {temp_reason}"
|
||||
msg += strings("banned_reason").format(reas=temp_reason)
|
||||
try:
|
||||
if len(time_value[:-1]) < 3:
|
||||
await message.chat.ban_member(user_id, until_date=temp_ban)
|
||||
await message.reply_text(msg)
|
||||
else:
|
||||
await message.reply_text("You can't use more than 99")
|
||||
await message.reply_text(strings("no_more_99"))
|
||||
except AttributeError:
|
||||
pass
|
||||
return
|
||||
if reason:
|
||||
msg += f"**Reason:** {reason}"
|
||||
msg += strings("banned_reason").format(reas=reason)
|
||||
keyboard = ikb({"🚨 Unban 🚨": f"unban_{user_id}"})
|
||||
try:
|
||||
await message.chat.ban_member(user_id)
|
||||
|
|
@ -216,7 +218,8 @@ async def banFunc(client, message):
|
|||
@app.on_message(filters.command("unban", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def unban_func(_, message):
|
||||
@use_chat_lang()
|
||||
async def unban_func(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
# we don't need reasons for unban, also, we
|
||||
|
|
@ -226,49 +229,50 @@ async def unban_func(_, message):
|
|||
reply = message.reply_to_message
|
||||
|
||||
if reply and reply.sender_chat and reply.sender_chat != message.chat.id:
|
||||
return await message.reply_text("You cannot unban a channel")
|
||||
return await message.reply_text(strings("unban_channel_err"))
|
||||
|
||||
if len(message.command) == 2:
|
||||
user = message.text.split(None, 1)[1]
|
||||
elif len(message.command) == 1 and reply:
|
||||
user = message.reply_to_message.from_user.id
|
||||
else:
|
||||
return await message.reply_text("Provide a username or reply to a user's message to unban.")
|
||||
return await message.reply_text(strings("give_unban_user"))
|
||||
await message.chat.unban_member(user)
|
||||
umention = (await app.get_users(user)).mention
|
||||
await message.reply_text(f"Unbanned! {umention}")
|
||||
await message.reply_text(strings("unban_success").format(umention=umention))
|
||||
|
||||
|
||||
# Ban users listed in a message
|
||||
@app.on_message(filters.user(SUDO) & filters.command("listban", COMMAND_HANDLER) & filters.group)
|
||||
@ratelimiter
|
||||
async def list_ban_(c, message):
|
||||
@use_chat_lang()
|
||||
async def list_ban_(c, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
userid, msglink_reason = await extract_user_and_reason(message)
|
||||
if not userid or not msglink_reason:
|
||||
return await message.reply_text("Provide a userid/username along with message link and reason to list-ban")
|
||||
return await message.reply_text(strings("give_idban_with_msg_link"))
|
||||
if len(msglink_reason.split(" ")) == 1: # message link included with the reason
|
||||
return await message.reply_text("You must provide a reason to list-ban")
|
||||
return await message.reply_text(strings("give_reason_list_ban"))
|
||||
# seperate messge link from reason
|
||||
lreason = msglink_reason.split()
|
||||
messagelink, reason = lreason[0], " ".join(lreason[1:])
|
||||
|
||||
if not re.search(r"(https?://)?t(elegram)?\.me/\w+/\d+", messagelink): # validate link
|
||||
return await message.reply_text("Invalid message link provided")
|
||||
return await message.reply_text(strings("invalid_tg_link"))
|
||||
|
||||
if userid == c.me.id:
|
||||
return await message.reply_text("I can't ban myself.")
|
||||
return await message.reply_text(strings("ban_self_err"))
|
||||
if userid in SUDO:
|
||||
return await message.reply_text("You Wanna Ban The Elevated One?, RECONSIDER!")
|
||||
return await message.reply_text(strings("ban_sudo_err"))
|
||||
splitted = messagelink.split("/")
|
||||
uname, mid = splitted[-2], int(splitted[-1])
|
||||
m = await message.reply_text("`Banning User from multiple groups. This may take some time`")
|
||||
m = await message.reply_text(strings("multiple_ban_progress"))
|
||||
try:
|
||||
msgtext = (await app.get_messages(uname, mid)).text
|
||||
gusernames = re.findall(r"@\w+", msgtext)
|
||||
except:
|
||||
return await m.edit_text("Could not get group usernames")
|
||||
return await m.edit_text(strings("failed_get_uname"))
|
||||
count = 0
|
||||
for username in gusernames:
|
||||
try:
|
||||
|
|
@ -281,40 +285,32 @@ async def list_ban_(c, message):
|
|||
count += 1
|
||||
mention = (await app.get_users(userid)).mention
|
||||
|
||||
msg = f"""
|
||||
**List-Banned User:** {mention}
|
||||
**Banned User ID:** `{userid}`
|
||||
**Admin:** {message.from_user.mention}
|
||||
**Affected chats:** `{count}`
|
||||
**Reason:** {reason}
|
||||
"""
|
||||
msg = strings("listban_msg").format(mention=mention, uid=userid, frus=message.from_user.mention, ct=count, reas=reason)
|
||||
await m.edit_text(msg)
|
||||
|
||||
|
||||
# Unban users listed in a message
|
||||
@app.on_message(filters.user(SUDO) & filters.command("listunban", COMMAND_HANDLER) & filters.group)
|
||||
@ratelimiter
|
||||
async def list_unban_(c, message):
|
||||
@use_chat_lang()
|
||||
async def list_unban_(c, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
userid, msglink = await extract_user_and_reason(message)
|
||||
if not userid or not msglink:
|
||||
return await message.reply_text("Provide a userid/username along with message link to list-unban")
|
||||
return await message.reply_text(strings("give_idunban_with_msg_link"))
|
||||
|
||||
if not re.search(r"(https?://)?t(elegram)?\.me/\w+/\d+", msglink): # validate link
|
||||
return await message.reply_text("Invalid message link provided")
|
||||
return await message.reply_text(strings("invalid_tg_link"))
|
||||
|
||||
splitted = msglink.split("/")
|
||||
uname, mid = splitted[-2], int(splitted[-1])
|
||||
m = await message.reply_text(
|
||||
"`Unbanning User from multiple groups. \
|
||||
This may take some time`"
|
||||
)
|
||||
m = await message.reply_text(strings("multiple_unban_progress"))
|
||||
try:
|
||||
msgtext = (await app.get_messages(uname, mid)).text
|
||||
gusernames = re.findall(r"@\w+", msgtext)
|
||||
except:
|
||||
return await m.edit_text("Could not get the group usernames")
|
||||
return await m.edit_text(strings("failed_get_uname"))
|
||||
count = 0
|
||||
for username in gusernames:
|
||||
try:
|
||||
|
|
@ -326,12 +322,7 @@ async def list_unban_(c, message):
|
|||
continue
|
||||
count += 1
|
||||
mention = (await app.get_users(userid)).mention
|
||||
msg = f"""
|
||||
**List-Unbanned User:** {mention}
|
||||
**Unbanned User ID:** `{userid}`
|
||||
**Admin:** {message.from_user.mention}
|
||||
**Affected chats:** `{count}`
|
||||
"""
|
||||
msg = strings("listunban_msg").format(mention=mention, uid=userid, frus=message.from_user.mention, ct=count)
|
||||
await m.edit_text(msg)
|
||||
|
||||
|
||||
|
|
@ -339,37 +330,39 @@ async def list_unban_(c, message):
|
|||
@app.on_message(filters.command("del", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_delete_messages")
|
||||
@ratelimiter
|
||||
async def deleteFunc(_, message):
|
||||
@use_chat_lang()
|
||||
async def deleteFunc(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
if not message.reply_to_message:
|
||||
return await message.reply_text("Reply To A Message To Delete It")
|
||||
return await message.reply_text(strings("delete_no_reply"))
|
||||
try:
|
||||
await message.reply_to_message.delete()
|
||||
await message.delete()
|
||||
except:
|
||||
await message.reply("Please give me delete message permission.")
|
||||
await message.reply(strings("no_delete_perm"))
|
||||
|
||||
|
||||
# Promote Members
|
||||
@app.on_message(filters.command(["promote", "fullpromote"], COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_promote_members")
|
||||
@ratelimiter
|
||||
async def promoteFunc(client, message):
|
||||
@use_chat_lang()
|
||||
async def promoteFunc(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
try:
|
||||
user_id = await extract_user(message)
|
||||
umention = (await app.get_users(user_id)).mention
|
||||
except:
|
||||
return await message.reply("⚠️ Invalid userid/username")
|
||||
return await message.reply(strings("invalid_id_uname"))
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
bot = await app.get_chat_member(message.chat.id, client.me.id)
|
||||
if user_id == client.me.id:
|
||||
return await message.reply_text("I can't promote myself.")
|
||||
return await message.reply_text(strings("promote_self_err"))
|
||||
if not bot.privileges.can_promote_members:
|
||||
return await message.reply_text("I don't have enough permissions")
|
||||
return await message.reply_text(strings("no_promote_perm"))
|
||||
if message.command[0][0] == "f":
|
||||
await message.chat.promote_member(
|
||||
user_id,
|
||||
|
|
@ -381,10 +374,10 @@ async def promoteFunc(client, message):
|
|||
can_pin_messages=bot.can_pin_messages,
|
||||
can_promote_members=bot.can_promote_members,
|
||||
can_manage_chat=bot.can_manage_chat,
|
||||
can_manage_voice_chats=bot.can_manage_voice_chats
|
||||
can_manage_voice_chats=bot.can_manage_voice_chats,
|
||||
),
|
||||
)
|
||||
)
|
||||
return await message.reply_text(f"Fully Promoted! {umention}")
|
||||
return await message.reply_text(strings("full_promote").format(umention=umention))
|
||||
|
||||
await message.chat.promote_member(
|
||||
user_id,
|
||||
|
|
@ -396,29 +389,28 @@ async def promoteFunc(client, message):
|
|||
can_pin_messages=False,
|
||||
can_promote_members=False,
|
||||
can_manage_chat=bot.can_manage_chat,
|
||||
can_manage_voice_chats=bot.can_manage_voice_chats
|
||||
can_manage_voice_chats=bot.can_manage_voice_chats,
|
||||
),
|
||||
)
|
||||
)
|
||||
await message.reply_text(f"Promoted! {umention}")
|
||||
await message.reply_text(strings("normal_promote").format(umention=umention))
|
||||
|
||||
|
||||
# Demote Member
|
||||
@app.on_message(filters.command("demote", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def demote(client, message):
|
||||
@use_chat_lang()
|
||||
async def demote(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
user_id = await extract_user(message)
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
if user_id == client.me.id:
|
||||
return await message.reply_text("I can't demote myself.")
|
||||
return await message.reply_text(strings("demote_self_err"))
|
||||
if user_id in SUDO:
|
||||
return await message.reply_text("You wanna demote the elevated one?")
|
||||
await message.chat.promote_member(
|
||||
user_id=user_id
|
||||
)
|
||||
return await message.reply_text(strings("demote_sudo_err"))
|
||||
await message.chat.promote_member(user_id=user_id)
|
||||
umention = (await app.get_users(user_id)).mention
|
||||
await message.reply_text(f"Demoted! {umention}")
|
||||
|
||||
|
|
@ -427,27 +419,28 @@ async def demote(client, message):
|
|||
@app.on_message(filters.command(["pin", "unpin"], COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_pin_messages")
|
||||
@ratelimiter
|
||||
async def pin(_, message):
|
||||
@use_chat_lang()
|
||||
async def pin(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
if not message.reply_to_message:
|
||||
return await message.reply_text("Reply to a message to pin/unpin it.")
|
||||
return await message.reply_text(strings("pin_no_reply"))
|
||||
r = message.reply_to_message
|
||||
try:
|
||||
if message.command[0][0] == "u":
|
||||
await r.unpin()
|
||||
return await message.reply_text(
|
||||
f"**Unpinned [this]({r.link}) message.**",
|
||||
strings("unpin_success").format(link=r.link),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
await r.pin(disable_notification=True)
|
||||
await message.reply(
|
||||
f"**Pinned [this]({r.link}) message.**",
|
||||
strings("pin_success").format(link=r.link),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
except ChatAdminRequired:
|
||||
await message.reply(
|
||||
"Please give me admin access to use this command.",
|
||||
strings("pin_no_perm"),
|
||||
disable_web_page_preview=True,
|
||||
)
|
||||
|
||||
|
|
@ -456,7 +449,8 @@ async def pin(_, message):
|
|||
@app.on_message(filters.command(["mute", "tmute"], COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def mute(client, message):
|
||||
@use_chat_lang()
|
||||
async def mute(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
try:
|
||||
|
|
@ -464,24 +458,24 @@ async def mute(client, message):
|
|||
except Exception as err:
|
||||
return await message.reply(f"ERROR: {err}")
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
if user_id == client.me.id:
|
||||
return await message.reply_text("I can't mute myself.")
|
||||
return await message.reply_text(strings("mute_self_err"))
|
||||
if user_id in SUDO:
|
||||
return await message.reply_text("You wanna mute the elevated one?, RECONSIDER!")
|
||||
return await message.reply_text(strings("mute_sudo_err"))
|
||||
if user_id in (await list_admins(message.chat.id)):
|
||||
return await message.reply_text("I can't mute an admin, You know the rules, so do i.")
|
||||
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 = f"**Muted User:** {mention}\n" f"**Muted By:** {message.from_user.mention if message.from_user else 'Anon'}\n"
|
||||
msg = strings("muted_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]
|
||||
temp_reason = split[1] if len(split) > 1 else ""
|
||||
temp_mute = await time_converter(message, time_value)
|
||||
msg += f"**Muted For:** {time_value}\n"
|
||||
msg += strings("muted_time").format(val=time_value)
|
||||
if temp_reason:
|
||||
msg += f"**Reason:** {temp_reason}"
|
||||
msg += strings("banned_reason").format(reas=temp_reason)
|
||||
try:
|
||||
if len(time_value[:-1]) < 3:
|
||||
await message.chat.restrict_member(
|
||||
|
|
@ -491,12 +485,12 @@ async def mute(client, message):
|
|||
)
|
||||
await message.reply_text(msg, reply_markup=keyboard)
|
||||
else:
|
||||
await message.reply_text("You can't use more than 99")
|
||||
await message.reply_text(strings("no_more_99"))
|
||||
except AttributeError:
|
||||
pass
|
||||
return
|
||||
if reason:
|
||||
msg += f"**Reason:** {reason}"
|
||||
msg += strings("banned_reason").format(reas=reason)
|
||||
await message.chat.restrict_member(user_id, permissions=ChatPermissions())
|
||||
await message.reply_text(msg, reply_markup=keyboard)
|
||||
|
||||
|
|
@ -505,67 +499,66 @@ async def mute(client, message):
|
|||
@app.on_message(filters.command("unmute", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def unmute(_, message):
|
||||
@use_chat_lang()
|
||||
async def unmute(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
user_id = await extract_user(message)
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
await message.chat.unban_member(user_id)
|
||||
umention = (await app.get_users(user_id)).mention
|
||||
await message.reply_text(f"Unmuted! {umention}")
|
||||
(await app.get_users(user_id)).mention
|
||||
await message.reply_text(strings("unmute_msg"))
|
||||
|
||||
|
||||
@app.on_message(filters.command(["warn", "dwarn"], COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def warn_user(client, message):
|
||||
@use_chat_lang()
|
||||
async def warn_user(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
user_id, reason = await extract_user_and_reason(message)
|
||||
chat_id = message.chat.id
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
if user_id == client.me.id:
|
||||
return await message.reply_text("I can't warn myself, i can leave if you want.")
|
||||
return await message.reply_text(strings("warn_self_err"))
|
||||
if user_id in SUDO:
|
||||
return await message.reply_text("You Wanna Warn The Elevated One?, RECONSIDER!")
|
||||
return await message.reply_text(strings("warn_sudo_err"))
|
||||
if user_id in (await list_admins(chat_id)):
|
||||
return await message.reply_text("I can't warn an admin, You know the rules, so do i.")
|
||||
return await message.reply_text(strings("warn_admin_err"))
|
||||
user, warns = await asyncio.gather(
|
||||
app.get_users(user_id),
|
||||
get_warn(chat_id, await int_to_alpha(user_id)),
|
||||
)
|
||||
mention = user.mention
|
||||
keyboard = ikb({"🚨 Remove Warn 🚨": f"unwarn_{user_id}"})
|
||||
keyboard = ikb({strings("rmwarn_btn"): f"unwarn_{user_id}"})
|
||||
warns = warns["warns"] if warns else 0
|
||||
if message.command[0][0] == "d":
|
||||
await message.reply_to_message.delete()
|
||||
if warns >= 2:
|
||||
await message.chat.ban_member(user_id)
|
||||
await message.reply_text(f"Number of warns of {mention} exceeded, BANNED!")
|
||||
await message.reply_text(strings("exceed_warn_msg").format(mention=mention))
|
||||
await remove_warns(chat_id, await int_to_alpha(user_id))
|
||||
else:
|
||||
warn = {"warns": warns + 1}
|
||||
msg = f"""
|
||||
**Warned User:** {mention}
|
||||
**Warned By:** {message.from_user.mention if message.from_user else 'Anon'}
|
||||
**Reason:** {reason or 'No Reason Provided.'}
|
||||
**Warns:** {warns + 1}/3"""
|
||||
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)
|
||||
|
||||
|
||||
@app.on_callback_query(filters.regex("unwarn_"))
|
||||
@ratelimiter
|
||||
async def remove_warning(_, cq):
|
||||
@use_chat_lang()
|
||||
async def remove_warning(_, cq, strings):
|
||||
from_user = cq.from_user
|
||||
chat_id = cq.message.chat.id
|
||||
permissions = await member_permissions(chat_id, from_user.id)
|
||||
permission = "can_restrict_members"
|
||||
if permission not in permissions:
|
||||
return await cq.answer(
|
||||
"You don't have enough permissions to perform this action.\n" + f"Permission needed: {permission}",
|
||||
strings("no_permission_error").format(permissions=permission),
|
||||
show_alert=True,
|
||||
)
|
||||
user_id = cq.data.split("_")[1]
|
||||
|
|
@ -573,52 +566,53 @@ async def remove_warning(_, cq):
|
|||
if warns:
|
||||
warns = warns["warns"]
|
||||
if not warns or warns == 0:
|
||||
return await cq.answer("User has no warnings.")
|
||||
return await cq.answer(strings("user_no_warn").format(mention=cq.message.reply_to_message.from_user.id))
|
||||
warn = {"warns": warns - 1}
|
||||
await add_warn(chat_id, await int_to_alpha(user_id), warn)
|
||||
text = cq.message.text.markdown
|
||||
text = f"~~{text}~~\n\n"
|
||||
text += f"__Warn removed by {from_user.mention}__"
|
||||
text += strings("unwarn_msg").format(mention=from_user.mention)
|
||||
await cq.message.edit(text)
|
||||
|
||||
|
||||
@app.on_callback_query(filters.regex("unmute_"))
|
||||
@ratelimiter
|
||||
async def unmute_user(_, cq):
|
||||
@use_chat_lang()
|
||||
async def unmute_user(_, cq, strings):
|
||||
from_user = cq.from_user
|
||||
chat_id = cq.message.chat.id
|
||||
permissions = await member_permissions(chat_id, from_user.id)
|
||||
permission = "can_restrict_members"
|
||||
if permission not in permissions:
|
||||
return await cq.answer(
|
||||
"You don't have enough permissions to perform this action.\n" + f"Permission needed: {permission}",
|
||||
strings("no_permission_error").format(permissions=permission),
|
||||
show_alert=True,
|
||||
)
|
||||
user_id = cq.data.split("_")[1]
|
||||
text = cq.message.text.markdown
|
||||
text = f"~~{text}~~\n\n"
|
||||
text += f"__Mute removed by {from_user.mention}__"
|
||||
text += strings("rmmute_msg").format(mention=from_user.mention)
|
||||
await cq.message.chat.unban_member(user_id)
|
||||
await cq.message.edit(text)
|
||||
|
||||
|
||||
@app.on_callback_query(filters.regex("unban_"))
|
||||
@ratelimiter
|
||||
async def unban_user(_, cq):
|
||||
@use_chat_lang()
|
||||
async def unban_user(_, cq, strings):
|
||||
from_user = cq.from_user
|
||||
chat_id = cq.message.chat.id
|
||||
permissions = await member_permissions(chat_id, from_user.id)
|
||||
permission = "can_restrict_members"
|
||||
if permission not in permissions:
|
||||
return await cq.answer(
|
||||
"You don't have enough permissions to perform this action.\n" + f"Permission needed: {permission}",
|
||||
strings("no_permission_error").format(permissions=permission),
|
||||
show_alert=True,
|
||||
)
|
||||
user_id = cq.data.split("_")[1]
|
||||
(await app.get_users(user_id)).mention
|
||||
text = cq.message.text.markdown
|
||||
text = f"~~{text}~~\n\n"
|
||||
text += f"__Banned removed by {from_user.mention}__"
|
||||
text += strings("unban_msg").format(mention=from_user.mention)
|
||||
await cq.message.chat.unban_member(user_id)
|
||||
await cq.message.edit(text)
|
||||
|
||||
|
|
@ -627,11 +621,12 @@ async def unban_user(_, cq):
|
|||
@app.on_message(filters.command("rmwarn", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_restrict_members")
|
||||
@ratelimiter
|
||||
async def remove_warnings(_, message):
|
||||
@use_chat_lang()
|
||||
async def remove_warnings(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
if not message.reply_to_message:
|
||||
return await message.reply_text("Reply to a message to remove a user's warnings.")
|
||||
return await message.reply_text(strings("reply_to_rm_warn"))
|
||||
user_id = message.reply_to_message.from_user.id
|
||||
mention = message.reply_to_message.from_user.mention
|
||||
chat_id = message.chat.id
|
||||
|
|
@ -639,53 +634,55 @@ async def remove_warnings(_, message):
|
|||
if warns:
|
||||
warns = warns["warns"]
|
||||
if warns == 0 or not warns:
|
||||
await message.reply_text(f"{mention} have no warnings.")
|
||||
await message.reply_text(strings("user_no_warn").format(mention=mention))
|
||||
else:
|
||||
await remove_warns(chat_id, await int_to_alpha(user_id))
|
||||
await message.reply_text(f"Removed warnings of {mention}.")
|
||||
await message.reply_text(strings("rmwarn_msg").format(mention=mention))
|
||||
|
||||
|
||||
# Warns
|
||||
@app.on_message(filters.command("warns", COMMAND_HANDLER) & filters.group)
|
||||
@capture_err
|
||||
@ratelimiter
|
||||
async def check_warns(_, message):
|
||||
@use_chat_lang()
|
||||
async def check_warns(_, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
user_id = await extract_user(message)
|
||||
if not user_id:
|
||||
return await message.reply_text("I can't find that user.")
|
||||
return await message.reply_text(strings("user_not_found"))
|
||||
warns = await get_warn(message.chat.id, await int_to_alpha(user_id))
|
||||
mention = (await app.get_users(user_id)).mention
|
||||
if warns:
|
||||
warns = warns["warns"]
|
||||
else:
|
||||
return await message.reply_text(f"{mention} has no warnings.")
|
||||
return await message.reply_text(f"{mention} has {warns}/3 warnings.")
|
||||
return await message.reply_text(strings("user_no_warn").format(mention=mention))
|
||||
return await message.reply_text(strings("ch_warn_msg").format(mention=mention, warns=warns))
|
||||
|
||||
|
||||
# Report User in Group
|
||||
@app.on_message((filters.command("report", COMMAND_HANDLER) | filters.command(["admins", "admin"], prefixes="@")) & filters.group)
|
||||
@capture_err
|
||||
@ratelimiter
|
||||
async def report_user(_, message):
|
||||
@use_chat_lang()
|
||||
async def report_user(_, message, strings):
|
||||
if not message.reply_to_message:
|
||||
return await message.reply_text("Reply to a message to report that user.")
|
||||
return await message.reply_text(strings("report_no_reply"))
|
||||
reply = message.reply_to_message
|
||||
reply_id = reply.from_user.id if reply.from_user else reply.sender_chat.id
|
||||
user_id = message.from_user.id if message.from_user else message.sender_chat.id
|
||||
if reply_id == user_id:
|
||||
return await message.reply_text("Why are you reporting yourself ?")
|
||||
return await message.reply_text(strings("report_self_err"))
|
||||
|
||||
list_of_admins = await list_admins(message.chat.id)
|
||||
linked_chat = (await app.get_chat(message.chat.id)).linked_chat
|
||||
if linked_chat is None:
|
||||
if reply_id in list_of_admins or reply_id == message.chat.id:
|
||||
return await message.reply_text("Do you know that the user you are replying is an admin ?")
|
||||
return await message.reply_text(strings("reported_is_admin"))
|
||||
elif reply_id in list_of_admins or reply_id == message.chat.id or reply_id == linked_chat.id:
|
||||
return await message.reply_text("Do you know that the user you are replying is an admin ?")
|
||||
return await message.reply_text(strings("reported_is_admin"))
|
||||
user_mention = reply.from_user.mention if reply.from_user else reply.sender_chat.title
|
||||
text = f"Reported {user_mention} to admins!"
|
||||
text = strings("report_msg").format(user_mention=user_mention)
|
||||
admin_data = [m async for m in app.get_chat_members(message.chat.id, filter=enums.ChatMembersFilter.ADMINISTRATORS)]
|
||||
for admin in admin_data:
|
||||
if admin.user.is_bot or admin.user.is_deleted:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
from pyrogram import filters
|
||||
from pyrogram.errors import MessageNotModified, MessageTooLong
|
||||
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.core.message_utils import *
|
||||
from misskaty.core.decorator.ratelimiter import ratelimiter
|
||||
|
|
@ -10,9 +11,10 @@ from misskaty.vars import COMMAND_HANDLER, OPENAI_API
|
|||
|
||||
@app.on_message(filters.command("ask", COMMAND_HANDLER))
|
||||
@ratelimiter
|
||||
async def chatbot(c, m):
|
||||
@use_chat_lang()
|
||||
async def chatbot(c, m, strings):
|
||||
if len(m.command) == 1:
|
||||
return await kirimPesan(m, f"Please use command <code>/{m.command[0]} [question]</code> to ask your question.")
|
||||
return await kirimPesan(m, strings("no_question").format(cmd=m.command[0]), quote=True)
|
||||
pertanyaan = m.text.split(" ", maxsplit=1)[1]
|
||||
headers = {
|
||||
"Content-Type": "application/json",
|
||||
|
|
@ -28,7 +30,7 @@ async def chatbot(c, m):
|
|||
},
|
||||
],
|
||||
}
|
||||
msg = await kirimPesan(m, "Wait a moment looking for your answer..")
|
||||
msg = await kirimPesan(m, strings("find_answers_str"), quote=True)
|
||||
try:
|
||||
response = (await http.post("https://api.openai.com/v1/chat/completions", headers=headers, json=json_data)).json()
|
||||
if err := response.get("error"):
|
||||
|
|
@ -37,6 +39,6 @@ async def chatbot(c, m):
|
|||
await editPesan(msg, answer)
|
||||
except MessageTooLong:
|
||||
answerlink = await post_to_telegraph(False, "MissKaty ChatBot ", answer)
|
||||
await editPesan(msg, f"Question for your answer has exceeded TG text limit, check this link to view.\n\n{answerlink}", disable_web_page_preview=True)
|
||||
await editPesan(msg, strings("answers_too_long").format(answerlink=answerlink), disable_web_page_preview=True)
|
||||
except Exception as err:
|
||||
await editPesan(msg, f"Oppss. ERROR: {str(err)}")
|
||||
await editPesan(msg, f"ERROR: {str(err)}")
|
||||
|
|
|
|||
|
|
@ -17,11 +17,9 @@ from pyrogram import enums, filters
|
|||
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
|
||||
from misskaty import app, user, botStartTime, BOT_NAME
|
||||
from misskaty.helper import http
|
||||
from misskaty.helper.human_read import get_readable_file_size, get_readable_time
|
||||
from misskaty.core.message_utils import editPesan, hapusPesan, kirimPesan
|
||||
from misskaty.vars import COMMAND_HANDLER, SUDO
|
||||
from utils import LOGGER
|
||||
|
||||
__MODULE__ = "DevCommand"
|
||||
__HELP__ = """
|
||||
|
|
@ -67,8 +65,8 @@ async def log_file(bot, message):
|
|||
@app.on_message(filters.command(["donate"], COMMAND_HANDLER))
|
||||
async def donate(_, message):
|
||||
await message.reply_photo(
|
||||
"AgACAgQAAxkBAAECsVNjbMvjxbN4gRafvNBH-Kv-Zqml8wACzq4xG95tbVPDeZ_UusonbAAIAQADAgADeQAHHgQ",
|
||||
caption=f"Hai {message.from_user.mention}, jika kamu merasa bot ini berguna bisa melakukan donasi dengan scan kode QRIS diatas untuk kebutuhan server dan lainnya. Terimakasih..",
|
||||
"https://telegra.ph/file/2acf7698f300ef3d9138f.jpg",
|
||||
caption=f"Hai {message.from_user.mention}, jika kamu merasa bot ini berguna bisa melakukan donasi dengan scan kode QRIS diatas yaa. Terimakasih..",
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -165,7 +163,7 @@ async def evaluation_cmd_t(_, m):
|
|||
trace_output = "❌ MISSING ATTRIBUTE:\n"
|
||||
trace_output += f"{e}"
|
||||
exc = trace_output
|
||||
except SyntaxError as e:
|
||||
except SyntaxError:
|
||||
trace = traceback.format_exc()
|
||||
splitted = str(trace).split("\n")
|
||||
end_split = len(splitted)
|
||||
|
|
@ -241,7 +239,7 @@ async def update_restart(_, message):
|
|||
except Exception as e:
|
||||
return await message.reply_text(str(e))
|
||||
msg = await message.reply_text("<b>Updated with default branch, restarting now.</b>")
|
||||
with open('restart.pickle', 'wb') as status:
|
||||
with open("restart.pickle", "wb") as status:
|
||||
pickle.dump([message.chat.id, msg.id], status)
|
||||
os.execvp(sys.executable, [sys.executable, "-m", "misskaty"])
|
||||
|
||||
|
|
|
|||
|
|
@ -162,11 +162,7 @@ async def fbdl(client, message):
|
|||
obj = SmartDL(url, progress_bar=False)
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ 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.vars import COMMAND_HANDLER
|
||||
|
|
@ -157,3 +158,10 @@ async def memify(client, message):
|
|||
await message.reply("Gunakan command <b>/mmf <text></b> dengan reply ke sticker, pisahkan dengan ; untuk membuat posisi text dibawah.")
|
||||
else:
|
||||
await message.reply("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)
|
||||
|
|
@ -8,7 +8,6 @@
|
|||
import datetime
|
||||
import os
|
||||
import time
|
||||
import traceback
|
||||
from asyncio import gather, sleep
|
||||
from logging import getLogger
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ from misskaty import BOT_USERNAME, app
|
|||
from misskaty.core.message_utils import *
|
||||
from misskaty.core.decorator.errors import capture_err
|
||||
from misskaty.core.decorator.ratelimiter import ratelimiter
|
||||
from misskaty.helper import http, get_random_string, search_jw, GENRES_EMOJI, post_to_telegraph
|
||||
from misskaty.helper import http, get_random_string, search_jw, GENRES_EMOJI
|
||||
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
|
||||
|
||||
LOGGER = logging.getLogger(__name__)
|
||||
|
|
|
|||
102
misskaty/plugins/lang_setting.py
Normal file
102
misskaty/plugins/lang_setting.py
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
from functools import partial
|
||||
from typing import Union
|
||||
|
||||
from pyrogram import Client, filters
|
||||
from pyrogram.enums import ChatType
|
||||
from pyrogram.types import (
|
||||
CallbackQuery,
|
||||
InlineKeyboardButton,
|
||||
InlineKeyboardMarkup,
|
||||
Message,
|
||||
)
|
||||
from misskaty.vars import COMMAND_HANDLER
|
||||
from misskaty import app
|
||||
from database.locale_db import set_db_lang
|
||||
from ..core.decorator.permissions import require_admin
|
||||
from ..helper.localization import (
|
||||
default_language,
|
||||
get_locale_string,
|
||||
langdict,
|
||||
use_chat_lang,
|
||||
)
|
||||
|
||||
|
||||
def gen_langs_kb():
|
||||
langs = list(langdict)
|
||||
kb = []
|
||||
while langs:
|
||||
lang = langdict[langs[0]]["main"]
|
||||
a = [
|
||||
InlineKeyboardButton(
|
||||
f"{lang['language_flag']} {lang['language_name']}",
|
||||
callback_data=f"set_lang {langs[0]}",
|
||||
)
|
||||
]
|
||||
|
||||
langs.pop(0)
|
||||
if langs:
|
||||
lang = langdict[langs[0]]["main"]
|
||||
a.append(
|
||||
InlineKeyboardButton(
|
||||
f"{lang['language_flag']} {lang['language_name']}",
|
||||
callback_data=f"set_lang {langs[0]}",
|
||||
)
|
||||
)
|
||||
|
||||
langs.pop(0)
|
||||
kb.append(a)
|
||||
return kb
|
||||
|
||||
|
||||
@app.on_callback_query(filters.regex("^chlang$"))
|
||||
@app.on_message(filters.command(["setchatlang", "setlang"], COMMAND_HANDLER))
|
||||
@require_admin(allow_in_private=True)
|
||||
@use_chat_lang()
|
||||
async def chlang(c: Client, m: Union[CallbackQuery, Message], strings):
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
*gen_langs_kb(),
|
||||
[InlineKeyboardButton(strings("back_btn", context="general"), callback_data="start_back")],
|
||||
]
|
||||
)
|
||||
|
||||
if isinstance(m, CallbackQuery):
|
||||
msg = m.message
|
||||
sender = msg.edit_text
|
||||
else:
|
||||
msg = m
|
||||
sender = msg.reply_text
|
||||
|
||||
res = strings("language_changer_private") if msg.chat.type == ChatType.PRIVATE else strings("language_changer_chat")
|
||||
|
||||
await sender(res, reply_markup=keyboard)
|
||||
|
||||
|
||||
@app.on_callback_query(filters.regex("^set_lang "))
|
||||
@require_admin(allow_in_private=True)
|
||||
@use_chat_lang()
|
||||
async def set_chat_lang(c: Client, m: CallbackQuery, strings):
|
||||
lang = m.data.split()[1]
|
||||
await set_db_lang(m.message.chat.id, m.message.chat.type, lang)
|
||||
|
||||
strings = partial(
|
||||
get_locale_string,
|
||||
langdict[lang].get("lang_setting", langdict[default_language]["lang_setting"]),
|
||||
lang,
|
||||
"lang_setting",
|
||||
)
|
||||
|
||||
if m.message.chat.type == ChatType.PRIVATE:
|
||||
keyboard = InlineKeyboardMarkup(
|
||||
inline_keyboard=[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
strings("back_btn", context="general"),
|
||||
callback_data="start_back",
|
||||
)
|
||||
]
|
||||
]
|
||||
)
|
||||
else:
|
||||
keyboard = None
|
||||
await m.message.edit_text(strings("language_changed_successfully"), reply_markup=keyboard)
|
||||
|
|
@ -16,29 +16,31 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
|||
from misskaty import app
|
||||
from misskaty.core.message_utils import *
|
||||
from misskaty.core.decorator.ratelimiter import ratelimiter
|
||||
from misskaty.helper import http, progress_for_pyrogram, runcmd, post_to_telegraph
|
||||
from misskaty.helper import progress_for_pyrogram, runcmd, post_to_telegraph
|
||||
from misskaty.helper.mediainfo_paste import mediainfo_paste
|
||||
from misskaty.helper.localization import use_chat_lang
|
||||
from misskaty.vars import COMMAND_HANDLER
|
||||
from utils import get_file_id
|
||||
|
||||
|
||||
@app.on_message(filters.command(["mediainfo"], COMMAND_HANDLER))
|
||||
@ratelimiter
|
||||
async def mediainfo(client, message):
|
||||
@use_chat_lang()
|
||||
async def mediainfo(client, message, strings):
|
||||
if not message.from_user:
|
||||
return
|
||||
if message.reply_to_message and message.reply_to_message.media:
|
||||
process = await kirimPesan(message, "`Processing, total time is based size of your files...`", quote=True)
|
||||
process = await kirimPesan(message, strings("processing_text"), quote=True)
|
||||
file_info = get_file_id(message.reply_to_message)
|
||||
if file_info is None:
|
||||
return await editPesan(process, "Please reply to valid media.")
|
||||
return await editPesan(process, strings("media_invalid"))
|
||||
if (message.reply_to_message.video and message.reply_to_message.video.file_size > 2097152000) or (message.reply_to_message.document and message.reply_to_message.document.file_size > 2097152000):
|
||||
return await editPesan(process, "Sorry, download limited to 2GB to reduce flood. You can convert your files to link.")
|
||||
return await editPesan(process, strings("dl_limit_exceeded"))
|
||||
c_time = time.time()
|
||||
dl = await message.reply_to_message.download(
|
||||
file_name="/downloads/",
|
||||
progress=progress_for_pyrogram,
|
||||
progress_args=("Trying to download..", process, c_time),
|
||||
progress_args=(strings("dl_args_text"), process, c_time),
|
||||
)
|
||||
file_path = path.join("/downloads/", path.basename(dl))
|
||||
output_ = await runcmd(f'mediainfo "{file_path}"')
|
||||
|
|
@ -51,21 +53,21 @@ JSON
|
|||
DETAILS
|
||||
{out or 'Not Supported'}
|
||||
"""
|
||||
text_ = file_info.message_type
|
||||
file_info.message_type
|
||||
try:
|
||||
link = await mediainfo_paste(out, "MissKaty Mediainfo")
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="💬 View in Web", url=link)]])
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
|
||||
except:
|
||||
try:
|
||||
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text)
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="💬 View in Web", url=link)]])
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
|
||||
except:
|
||||
markup = None
|
||||
with io.BytesIO(str.encode(body_text)) as out_file:
|
||||
out_file.name = "MissKaty_Mediainfo.txt"
|
||||
await message.reply_document(
|
||||
out_file,
|
||||
caption=f"ℹ️ <b>MEDIA INFO</b>\n\n**Request by:** {message.from_user.mention}",
|
||||
caption=strings("capt_media").format(ment=message.from_user.mention),
|
||||
thumb="assets/thumb.jpg",
|
||||
reply_markup=markup,
|
||||
)
|
||||
|
|
@ -77,11 +79,11 @@ DETAILS
|
|||
else:
|
||||
try:
|
||||
link = message.text.split(" ", maxsplit=1)[1]
|
||||
process = await kirimPesan(message, "`Mohon tunggu sejenak...`")
|
||||
process = await kirimPesan(message, strings("wait_msg"))
|
||||
try:
|
||||
output = subprocess.check_output(["mediainfo", f"{link}"]).decode("utf-8")
|
||||
except Exception:
|
||||
return await editPesan(process, "Sepertinya link yang kamu kirim tidak valid, pastikan direct link dan bisa di download.")
|
||||
return await editPesan(process, strings("err_link"))
|
||||
body_text = f"""
|
||||
MissKatyBot MediaInfo
|
||||
{output}
|
||||
|
|
@ -89,21 +91,21 @@ DETAILS
|
|||
# link = await post_to_telegraph(False, title, body_text)
|
||||
try:
|
||||
link = await mediainfo_paste(out, "MissKaty Mediainfo")
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="💬 View in Web", url=link)]])
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
|
||||
except:
|
||||
try:
|
||||
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text)
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="💬 View in Web", url=link)]])
|
||||
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
|
||||
except:
|
||||
markup = None
|
||||
with io.BytesIO(str.encode(output)) as out_file:
|
||||
out_file.name = "MissKaty_Mediainfo.txt"
|
||||
await message.reply_document(
|
||||
out_file,
|
||||
caption=f"Hasil mediainfo anda..\n\n**Request by:** {message.from_user.mention}",
|
||||
caption=strings("capt_media").format(ment=message.from_user.mention),
|
||||
thumb="assets/thumb.jpg",
|
||||
reply_markup=markup,
|
||||
)
|
||||
await process.delete()
|
||||
except IndexError:
|
||||
return await kirimPesan(message, "Gunakan command /mediainfo [link], atau reply telegram media dengan /mediainfo.")
|
||||
return await kirimPesan(message, strings("mediainfo_help").format(help=message.command[0]))
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@
|
|||
|
||||
import json
|
||||
import os
|
||||
import time
|
||||
import asyncio
|
||||
import traceback
|
||||
from PIL import Image
|
||||
from datetime import datetime
|
||||
from logging import getLogger
|
||||
from urllib.parse import quote
|
||||
|
||||
|
|
@ -63,11 +61,11 @@ async def readqr(c, m):
|
|||
if not m.reply_to_message.photo:
|
||||
return await m.reply("Please reply photo that contain valid QR Code.")
|
||||
foto = await m.reply_to_message.download()
|
||||
myfile = {'file': (foto, open(foto, 'rb'),'application/octet-stream')}
|
||||
url = 'http://api.qrserver.com/v1/read-qr-code/'
|
||||
myfile = {"file": (foto, open(foto, "rb"), "application/octet-stream")}
|
||||
url = "http://api.qrserver.com/v1/read-qr-code/"
|
||||
r = await http.post(url, files=myfile)
|
||||
os.remove(foto)
|
||||
if res := r.json()[0]['symbol'][0]['data'] is None:
|
||||
if res := r.json()[0]["symbol"][0]["data"] is None:
|
||||
return await kirimPesan(m, res)
|
||||
await kirimPesan(m, f"<b>QR Code Reader by @{c.me.username}:</b> <code>{r.json()[0]['symbol'][0]['data']}</code>", quote=True)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,7 @@ 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.errors import ChannelInvalid, ChannelPrivate, ChatAdminRequired, ChatNotModified
|
||||
from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup
|
||||
|
||||
from misskaty import BOT_NAME, BOT_USERNAME, app, scheduler
|
||||
|
|
@ -30,6 +29,7 @@ __HELP__ = """<b>Enable or disable nightmode (locks the chat at specified interv
|
|||
TIME_ZONE = pytz.timezone(TZ)
|
||||
reply_markup = InlineKeyboardMarkup([[InlineKeyboardButton(text="❤️", callback_data="nightmd")]])
|
||||
|
||||
|
||||
# Check calculate how long it will take to Ramadhan
|
||||
def puasa():
|
||||
now = datetime.now(pytz.timezone("Asia/Jakarta"))
|
||||
|
|
@ -43,6 +43,7 @@ def puasa():
|
|||
y = datetime(2022, 4, 2, 0, 0, 0)
|
||||
return y - x
|
||||
|
||||
|
||||
def tglsekarang():
|
||||
now = datetime.now(pytz.timezone("Asia/Jakarta"))
|
||||
days = ["Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu", "Minggu"]
|
||||
|
|
@ -66,84 +67,60 @@ def tglsekarang():
|
|||
jam = now.strftime("%H:%M")
|
||||
return f"{days[now.weekday()]}, {tgl} {month[now.month]} {tahun}"
|
||||
|
||||
|
||||
def extract_time(time_val: str):
|
||||
if any(time_val.endswith(unit) for unit in ('m', 'h')):
|
||||
if any(time_val.endswith(unit) for unit in ("m", "h")):
|
||||
unit = time_val[-1]
|
||||
time_num = time_val[:-1]
|
||||
if not time_num.isdigit():
|
||||
return ""
|
||||
if unit == 'm':
|
||||
if unit == "m":
|
||||
time = int(time_num) * 60
|
||||
elif unit == 'h':
|
||||
elif unit == "h":
|
||||
time = int(time_num) * 60 * 60
|
||||
else:
|
||||
return ""
|
||||
return time
|
||||
return ""
|
||||
|
||||
|
||||
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,
|
||||
f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`,"
|
||||
f"since {BOT_NAME} is not an admin in chat `{chat_id}`")
|
||||
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`," f"since {BOT_NAME} is not an admin in chat `{chat_id}`")
|
||||
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,
|
||||
f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`,"
|
||||
f"since {BOT_NAME} is not present in chat `{chat_id}`"
|
||||
" Removed group from list.")
|
||||
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`," f"since {BOT_NAME} is not present in chat `{chat_id}`" " Removed group from list.")
|
||||
except ChatNotModified:
|
||||
pass
|
||||
except Exception as e:
|
||||
await app.send_message(
|
||||
LOG_CHANNEL,
|
||||
f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`\n"
|
||||
f"ERROR: `{e}`")
|
||||
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`\n" f"ERROR: `{e}`")
|
||||
else:
|
||||
job = scheduler.get_job(f"enable_nightmode_{chat_id}")
|
||||
close_at = job.next_run_time
|
||||
await app.send_message(
|
||||
chat_id,
|
||||
f"#NIGHTMODE_HANDLER\n📆 {tglsekarang()}\n\n☀️ Group is Opening.\nWill be closed at {close_at}",
|
||||
reply_markup=reply_markup
|
||||
)
|
||||
await app.send_message(chat_id, f"#NIGHTMODE_HANDLER\n📆 {tglsekarang()}\n\n☀️ Group is Opening.\nWill be closed at {close_at}", reply_markup=reply_markup)
|
||||
|
||||
|
||||
async def mute_chat(chat_id: int):
|
||||
try:
|
||||
await app.set_chat_permissions(chat_id, ChatPermissions())
|
||||
except ChatAdminRequired:
|
||||
await app.send_message(
|
||||
LOG_CHANNEL,
|
||||
f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`,"
|
||||
f"since {BOT_NAME} is not an admin in chat `{chat_id}`")
|
||||
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`," f"since {BOT_NAME} is not an admin in chat `{chat_id}`")
|
||||
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,
|
||||
f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`,"
|
||||
f"since {BOT_NAME} is not present in chat `{chat_id}`"
|
||||
" Removed group from list.")
|
||||
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`," f"since {BOT_NAME} is not present in chat `{chat_id}`" " Removed group from list.")
|
||||
except ChatNotModified:
|
||||
pass
|
||||
except Exception as e:
|
||||
await app.send_message(
|
||||
LOG_CHANNEL,
|
||||
f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`\n"
|
||||
f"ERROR: `{e}`")
|
||||
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`\n" f"ERROR: `{e}`")
|
||||
else:
|
||||
job = scheduler.get_job(f"disable_nightmode_{chat_id}")
|
||||
open_at = job.next_run_time
|
||||
await app.send_message(
|
||||
chat_id,
|
||||
f"#NIGHTMODE_HANDLER\n📆 {tglsekarang()}\n\n🌗 Group is closing.\nWill be opened at {open_at}",
|
||||
reply_markup=reply_markup
|
||||
)
|
||||
await app.send_message(chat_id, f"#NIGHTMODE_HANDLER\n📆 {tglsekarang()}\n\n🌗 Group is closing.\nWill be opened at {open_at}", reply_markup=reply_markup)
|
||||
|
||||
|
||||
@app.on_message(filters.command("nightmode", COMMAND_HANDLER) & filters.group)
|
||||
@adminsOnly("can_change_info")
|
||||
|
|
@ -157,7 +134,7 @@ async def nightmode_handler(c, msg):
|
|||
scheduler.remove_job(job_id=f"disable_nightmode_{chat_id}")
|
||||
if not bool(scheduler.get_jobs()) and bool(scheduler.state):
|
||||
scheduler.shutdown()
|
||||
return await kirimPesan(msg, 'Nightmode disabled.')
|
||||
return await kirimPesan(msg, "Nightmode disabled.")
|
||||
return await kirimPesan(msg, "Nightmode isn't enabled in this chat.")
|
||||
|
||||
starttime = re.findall(r"-s=(\d+:\d+)", msg.text)
|
||||
|
|
@ -165,10 +142,7 @@ async def nightmode_handler(c, msg):
|
|||
now = datetime.now(TIME_ZONE)
|
||||
|
||||
try:
|
||||
start_timestamp = TIME_ZONE.localize(
|
||||
datetime.strptime(
|
||||
(now.strftime('%m:%d:%Y - ') + start),
|
||||
'%m:%d:%Y - %H:%M'))
|
||||
start_timestamp = TIME_ZONE.localize(datetime.strptime((now.strftime("%m:%d:%Y - ") + start), "%m:%d:%Y - %H:%M"))
|
||||
except ValueError:
|
||||
return await kirimPesan(msg, "Invalid time format. Use HH:MM format.")
|
||||
lockdur = re.findall(r"-e=(\w+)", msg.text)
|
||||
|
|
@ -176,53 +150,25 @@ async def nightmode_handler(c, msg):
|
|||
lock_dur = extract_time(lockdur.lower())
|
||||
|
||||
if not lock_dur:
|
||||
return await kirimPesan(
|
||||
msg,
|
||||
'Invalid time duration. Use proper format.'
|
||||
'\nExample: 6h (for 6 hours), 10m for 10 minutes.')
|
||||
return await kirimPesan(msg, "Invalid time duration. Use proper format." "\nExample: 6h (for 6 hours), 10m for 10 minutes.")
|
||||
|
||||
if start_timestamp < now:
|
||||
start_timestamp = start_timestamp + timedelta(days=1)
|
||||
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 kirimPesan(
|
||||
msg,
|
||||
'Already a schedule is running in this chat. Disable it using `-d` flag.')
|
||||
await kirimPesan(
|
||||
msg,
|
||||
'Successfully enabled nightmode in this chat.\n'
|
||||
f'Group will be locked at {start_timestamp.strftime("%H:%M:%S")}'
|
||||
f' and will be opened after {lockdur} everyday.')
|
||||
return await kirimPesan(msg, "Already a schedule is running in this chat. Disable it using `-d` flag.")
|
||||
await kirimPesan(msg, "Successfully enabled nightmode in this chat.\n" f'Group will be locked at {start_timestamp.strftime("%H:%M:%S")}' f" and will be opened after {lockdur} everyday.")
|
||||
if not bool(scheduler.state):
|
||||
scheduler.start()
|
||||
|
||||
|
||||
@app.on_callback_query(filters.regex(r"^nightmd$"))
|
||||
@ratelimiter
|
||||
async def callbackanightmd(c, q):
|
||||
await q.answer(
|
||||
f"🔖 Hai, Aku {BOT_USERNAME} dibuat menggunakan Framework Pyrogram v{__version__} dan Python 3.10.\n\nMau buat bot seperti ini? Yuuk belajar di @botindonesia\nOwner: @YasirArisM",
|
||||
show_alert=True
|
||||
)
|
||||
await q.answer(f"🔖 Hai, Aku {BOT_USERNAME} dibuat menggunakan Framework Pyrogram v{__version__} dan Python 3.10.\n\nMau buat bot seperti ini? Yuuk belajar di @botindonesia\nOwner: @YasirArisM", show_alert=True)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
* @projectName MissKatyPyro
|
||||
* Copyright @YasirPedia All rights reserved
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
from pyrogram import filters
|
||||
|
|
@ -14,6 +15,7 @@ from misskaty import app
|
|||
from misskaty.core.message_utils import *
|
||||
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.helper.http import http
|
||||
from misskaty.vars import COMMAND_HANDLER
|
||||
|
||||
|
|
@ -24,11 +26,12 @@ __HELP__ = "/ocr [reply to photo] - Read Text From Image"
|
|||
@app.on_message(filters.command(["ocr"], COMMAND_HANDLER))
|
||||
@capture_err
|
||||
@ratelimiter
|
||||
async def ocr(_, m):
|
||||
@use_chat_lang()
|
||||
async def ocr(_, m, strings):
|
||||
reply = m.reply_to_message
|
||||
if not reply or not reply.photo and not reply.sticker:
|
||||
return await kirimPesan(m, f"Reply photo with /{m.command[0]} command")
|
||||
msg = await kirimPesan(m, "Reading image...")
|
||||
return await kirimPesan(m, strings("no_photo").format(cmd=m.command[0]), quote=True)
|
||||
msg = await kirimPesan(m, strings("read_ocr"), quote=True)
|
||||
try:
|
||||
file_path = await reply.download()
|
||||
if reply.sticker:
|
||||
|
|
@ -41,7 +44,7 @@ async def ocr(_, m):
|
|||
follow_redirects=True,
|
||||
)
|
||||
).json()
|
||||
await editPesan(msg, f"Hasil OCR:\n<code>{req['text']}</code>")
|
||||
await editPesan(msg, strings("result_ocr").format(result=req["text"]))
|
||||
os.remove(file_path)
|
||||
except Exception as e:
|
||||
await editPesan(msg, str(e))
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from misskaty import app
|
|||
from misskaty.core.decorator.permissions import adminsOnly
|
||||
from misskaty.core.decorator.ratelimiter import ratelimiter
|
||||
from misskaty.core.message_utils import kirimPesan
|
||||
from misskaty.helper.localization import use_chat_lang
|
||||
from misskaty.vars import COMMAND_HANDLER
|
||||
|
||||
__MODULE__ = "SangMata"
|
||||
|
|
@ -19,28 +20,28 @@ This feature inspired from SangMata Bot. I'm created simple detection to check u
|
|||
filters.group & ~filters.bot & ~filters.via_bot,
|
||||
group=3,
|
||||
)
|
||||
async def cek_mataa(_, m):
|
||||
@use_chat_lang()
|
||||
async def cek_mataa(_, m, strings):
|
||||
if m.sender_chat or not await is_sangmata_on(m.chat.id):
|
||||
return
|
||||
if not await cek_userdata(m.from_user.id):
|
||||
return await add_userdata(m.from_user.id, m.from_user.username, m.from_user.first_name, m.from_user.last_name)
|
||||
username, first_name, last_name = await get_userdata(m.from_user.id)
|
||||
usernamebefore, first_name, lastname_before = await get_userdata(m.from_user.id)
|
||||
msg = ""
|
||||
if username != m.from_user.username or first_name != m.from_user.first_name or last_name != m.from_user.last_name:
|
||||
msg += "👀 <b>Mata MissKaty</b>\n\n"
|
||||
if username != m.from_user.username:
|
||||
username = "No Username" if not username else username
|
||||
msg += f"{m.from_user.mention} [<code>{m.from_user.id}</code>] changed username.\n"
|
||||
msg += f"From {username} ➡️ @{m.from_user.username}.\n"
|
||||
if usernamebefore != m.from_user.username or first_name != m.from_user.first_name or lastname_before != m.from_user.last_name:
|
||||
msg += f"👀 <b>Mata MissKaty</b>\n\n🌞 User: {m.from_user.mention} [<code>{m.from_user.id}</code>]\n"
|
||||
if usernamebefore != m.from_user.username:
|
||||
usernamebefore = f"@{usernamebefore}" if usernamebefore else strings("no_uname")
|
||||
usernameafter = f"@{m.from_user.username}" if m.from_user.username else strings("no_uname")
|
||||
msg += strings("uname_change_msg").format(bef=usernamebefore, aft=usernameafter)
|
||||
await add_userdata(m.from_user.id, m.from_user.username, m.from_user.first_name, m.from_user.last_name)
|
||||
if first_name != m.from_user.first_name:
|
||||
msg += f"{m.from_user.mention} [<code>{m.from_user.id}</code>] changed first_name.\n"
|
||||
msg += f"From {first_name} ➡️ {m.from_user.first_name}.\n"
|
||||
msg += strings("firstname_change_msg").format(bef=first_name, aft=m.from_user.first_name)
|
||||
await add_userdata(m.from_user.id, m.from_user.username, m.from_user.first_name, m.from_user.last_name)
|
||||
if last_name != m.from_user.last_name:
|
||||
last_name = "No Lastname" if not username else username
|
||||
msg += f"{m.from_user.mention} [<code>{m.from_user.id}</code>] changed last_name.\n"
|
||||
msg += f"From {last_name} ➡️ {m.from_user.last_name}."
|
||||
if lastname_before != m.from_user.last_name:
|
||||
lastname_before = lastname_before or strings("no_last_name")
|
||||
lastname_after = m.from_user.last_name or strings("no_last_name")
|
||||
msg += strings("lastname_change_msg").format(bef=lastname_before, aft=lastname_after)
|
||||
await add_userdata(m.from_user.id, m.from_user.username, m.from_user.first_name, m.from_user.last_name)
|
||||
if msg != "":
|
||||
await kirimPesan(m, msg, quote=True)
|
||||
|
|
@ -49,22 +50,23 @@ async def cek_mataa(_, m):
|
|||
@app.on_message(filters.group & filters.command("sangmata_set", COMMAND_HANDLER) & ~filters.bot & ~filters.via_bot)
|
||||
@adminsOnly("can_change_info")
|
||||
@ratelimiter
|
||||
async def set_mataa(_, m):
|
||||
@use_chat_lang()
|
||||
async def set_mataa(_, m, strings):
|
||||
if len(m.command) == 1:
|
||||
return await kirimPesan(m, f"Use <code>/{m.command[0]} on</code>, to enable sangmata. If you want disable, you can use off parameter.")
|
||||
return await kirimPesan(m, strings("set_sangmata_help").format(cmd=m.command[0]))
|
||||
if m.command[1] == "on":
|
||||
cekset = await is_sangmata_on(m.chat.id)
|
||||
if cekset:
|
||||
await kirimPesan(m, "SangMata already enabled in your groups.")
|
||||
await kirimPesan(m, strings("sangmata_already_on"))
|
||||
else:
|
||||
await sangmata_on(m.chat.id)
|
||||
await kirimPesan(m, "Sangmata enabled in your groups.")
|
||||
await kirimPesan(m, strings("sangmata_enabled"))
|
||||
elif m.command[1] == "off":
|
||||
cekset = await is_sangmata_on(m.chat.id)
|
||||
if not cekset:
|
||||
await kirimPesan(m, "SangMata already disabled in your groups.")
|
||||
await kirimPesan(m, strings("sangmata_already_off"))
|
||||
else:
|
||||
await sangmata_off(m.chat.id)
|
||||
await kirimPesan(m, "Sangmata has been disabled in your groups.")
|
||||
await kirimPesan(m, strings("sangmata_disabled"))
|
||||
else:
|
||||
await kirimPesan(m, "Unknown parameter, use only on/off parameter.")
|
||||
await kirimPesan(m, strings("wrong_param"))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
|||
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
|
||||
|
||||
__MODULE__ = "Stickers"
|
||||
|
|
@ -43,10 +44,11 @@ SUPPORTED_TYPES = ["jpeg", "png", "webp"]
|
|||
|
||||
@app.on_message(filters.command(["getsticker"], COMMAND_HANDLER))
|
||||
@ratelimiter
|
||||
async def getsticker_(c, m):
|
||||
@use_chat_lang()
|
||||
async def getsticker_(c, m, strings):
|
||||
if sticker := m.reply_to_message.sticker:
|
||||
if sticker.is_animated:
|
||||
await m.reply_text("Animated sticker is not supported!")
|
||||
await m.reply_text(strings("no_anim_stick"))
|
||||
else:
|
||||
with tempfile.TemporaryDirectory() as tempdir:
|
||||
path = os.path.join(tempdir, "getsticker")
|
||||
|
|
@ -56,11 +58,11 @@ async def getsticker_(c, m):
|
|||
)
|
||||
await m.reply_to_message.reply_document(
|
||||
document=sticker_file,
|
||||
caption=(f"<b>Emoji:</b> {sticker.emoji}\n" f"<b>Sticker ID:</b> <code>{sticker.file_id}</code>\n\n" f"<b>Send by:</b> @{BOT_USERNAME}"),
|
||||
caption=f"<b>Emoji:</b> {sticker.emoji}\n" f"<b>Sticker ID:</b> <code>{sticker.file_id}</code>\n\n" f"<b>Send by:</b> @{BOT_USERNAME}",
|
||||
)
|
||||
shutil.rmtree(tempdir, ignore_errors=True)
|
||||
else:
|
||||
await m.reply_text("This is not a sticker!")
|
||||
await m.reply_text(strings("not_sticker"))
|
||||
|
||||
|
||||
@app.on_message(filters.command("stickerid", COMMAND_HANDLER) & filters.reply)
|
||||
|
|
@ -72,9 +74,10 @@ async def getstickerid(c, m):
|
|||
|
||||
@app.on_message(filters.command("unkang", COMMAND_HANDLER) & filters.reply)
|
||||
@ratelimiter
|
||||
async def getstickerid(c, m):
|
||||
@use_chat_lang()
|
||||
async def getstickerid(c, m, strings):
|
||||
if m.reply_to_message.sticker:
|
||||
pp = await m.reply_text("Trying to remove from pack..")
|
||||
pp = await m.reply_text(strings("unkang_msg"))
|
||||
try:
|
||||
decoded = FileId.decode(m.reply_to_message.sticker.file_id)
|
||||
sticker = InputDocument(
|
||||
|
|
@ -83,19 +86,20 @@ async def getstickerid(c, m):
|
|||
file_reference=decoded.file_reference,
|
||||
)
|
||||
await app.invoke(RemoveStickerFromSet(sticker=sticker))
|
||||
await pp.edit("Sticker has been removed from your pack")
|
||||
await pp.edit(strings("unkang_success"))
|
||||
except Exception as e:
|
||||
await pp.edit(f"Failed remove sticker from your pack.\n\nERR: {e}")
|
||||
await pp.edit(strings("unkang_error").format(e=e))
|
||||
else:
|
||||
await m.reply_text(f"Please reply sticker that created by {c.me.username} to remove sticker from your pack.")
|
||||
await m.reply_text(strings("unkang_help").format(c=c.me.username))
|
||||
|
||||
|
||||
@app.on_message(filters.command(["curi", "kang"], COMMAND_HANDLER))
|
||||
@ratelimiter
|
||||
async def kang_sticker(c, m):
|
||||
@use_chat_lang()
|
||||
async def kang_sticker(c, m, strings):
|
||||
if not m.from_user:
|
||||
return await m.reply_text("You are anon admin, kang stickers in my pm.")
|
||||
prog_msg = await m.reply_text("Trying to steal your sticker...")
|
||||
return await m.reply_text(strings("anon_warn"))
|
||||
prog_msg = await m.reply_text(strings("kang_msg"))
|
||||
sticker_emoji = "🤔"
|
||||
packnum = 0
|
||||
packname_found = False
|
||||
|
|
@ -131,7 +135,7 @@ async def kang_sticker(c, m):
|
|||
animated = True
|
||||
elif reply.sticker:
|
||||
if not reply.sticker.file_name:
|
||||
return await prog_msg.edit_text("The sticker has no name.")
|
||||
return await prog_msg.edit_text(strings("stick_no_name"))
|
||||
if reply.sticker.emoji:
|
||||
sticker_emoji = reply.sticker.emoji
|
||||
animated = reply.sticker.is_animated
|
||||
|
|
@ -186,7 +190,7 @@ async def kang_sticker(c, m):
|
|||
sticker_emoji = "".join(set(EMOJI_PATTERN.findall("".join(m.command[2:])))) or sticker_emoji
|
||||
resize = True
|
||||
else:
|
||||
return await prog_msg.edit_text("Want me to guess the sticker? Please tag a sticker.")
|
||||
return await prog_msg.edit_text(strings("kang_help"))
|
||||
try:
|
||||
if resize:
|
||||
filename = resize_image(filename)
|
||||
|
|
@ -226,7 +230,7 @@ async def kang_sticker(c, m):
|
|||
msg_ = media.updates[-1].message
|
||||
stkr_file = msg_.media.document
|
||||
if packname_found:
|
||||
await prog_msg.edit_text("<code>Using existing sticker pack...</code>")
|
||||
await prog_msg.edit_text(strings("exist_pack"))
|
||||
await c.invoke(
|
||||
AddStickerToSet(
|
||||
stickerset=InputStickerSetShortName(short_name=packname),
|
||||
|
|
@ -241,7 +245,7 @@ async def kang_sticker(c, m):
|
|||
)
|
||||
)
|
||||
else:
|
||||
await prog_msg.edit_text("<b>Creating a new sticker pack...</b>")
|
||||
await prog_msg.edit_text(strings("new_packs"))
|
||||
stkr_title = f"{m.from_user.first_name}'s"
|
||||
if animated:
|
||||
stkr_title += "AnimPack"
|
||||
|
|
@ -271,12 +275,12 @@ async def kang_sticker(c, m):
|
|||
)
|
||||
except PeerIdInvalid:
|
||||
return await prog_msg.edit_text(
|
||||
"It looks like you've never interacted with me in private chat, you need to do that first..",
|
||||
strings("please_start_msg"),
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
"Click Me",
|
||||
strings("click_me"),
|
||||
url=f"https://t.me/{c.me.username}?start",
|
||||
)
|
||||
]
|
||||
|
|
@ -285,7 +289,7 @@ async def kang_sticker(c, m):
|
|||
)
|
||||
|
||||
except BadRequest:
|
||||
return await prog_msg.edit_text("Your Sticker Pack is full if your pack is not in v1 Type /kang 1, if it is not in v2 Type /kang 2 and so on.")
|
||||
return await prog_msg.edit_text(strings("pack_full"))
|
||||
except Exception as all_e:
|
||||
await prog_msg.edit_text(f"{all_e.__class__.__name__} : {all_e}")
|
||||
else:
|
||||
|
|
@ -293,14 +297,14 @@ async def kang_sticker(c, m):
|
|||
[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
text="👀 View Your Pack",
|
||||
text=strings("viewpack"),
|
||||
url=f"https://t.me/addstickers/{packname}",
|
||||
)
|
||||
]
|
||||
]
|
||||
)
|
||||
await prog_msg.edit_text(
|
||||
f"<b>Sticker successfully stolen!</b>\n<b>Emoji:</b> {sticker_emoji}",
|
||||
strings("kang_success").format(emot=sticker_emoji),
|
||||
reply_markup=markup,
|
||||
)
|
||||
# Cleanup
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ from pyrogram import filters
|
|||
from misskaty import app
|
||||
from misskaty.core.decorator.ratelimiter import ratelimiter
|
||||
from misskaty.core.message_utils import *
|
||||
from misskaty.helper import http
|
||||
from misskaty.vars import COMMAND_HANDLER
|
||||
|
||||
from .web_scraper import split_arr
|
||||
|
|
@ -18,6 +17,7 @@ LOGGER = logging.getLogger(__name__)
|
|||
SUB_TITLE_DICT = {}
|
||||
SUB_DL_DICT = {}
|
||||
|
||||
|
||||
# Get list title based on query
|
||||
async def getTitleSub(msg, kueri, CurrentPage, user):
|
||||
if not SUB_TITLE_DICT.get(msg.id):
|
||||
|
|
@ -32,7 +32,7 @@ async def getTitleSub(msg, kueri, CurrentPage, user):
|
|||
# await editPesan(msg, f"Sorry, could not find any result for: {kueri}")
|
||||
# return None, 0, None
|
||||
for sub in entry:
|
||||
title = sub.find('a').text
|
||||
title = sub.find("a").text
|
||||
link = f"https://subscene.com{sub.find('a').get('href')}"
|
||||
sdata.append({"title": title, "link": link})
|
||||
SUB_TITLE_DICT[msg.id] = [split_arr(sdata, 10), kueri]
|
||||
|
|
@ -54,12 +54,13 @@ async def getTitleSub(msg, kueri, CurrentPage, user):
|
|||
await editPesan(msg, "Sorry could not find any matching results!")
|
||||
return None, 0, None
|
||||
|
||||
|
||||
# Get list all subtitles from title
|
||||
async def getListSub(msg, link, CurrentPage, user):
|
||||
if not SUB_DL_DICT.get(msg.id):
|
||||
sdata = []
|
||||
scraper = cfscrape.create_scraper()
|
||||
kuki = {'LanguageFilter': "13,44,50"} # Only filter language English, Malay, Indonesian
|
||||
kuki = {"LanguageFilter": "13,44,50"} # Only filter language English, Malay, Indonesian
|
||||
r = scraper.get(link, cookies=kuki).text
|
||||
soup = BeautifulSoup(r, "lxml")
|
||||
for i in soup.findAll(class_="a1"):
|
||||
|
|
@ -92,6 +93,7 @@ async def getListSub(msg, link, CurrentPage, user):
|
|||
await editPesan(msg, "Sorry could not find any matching results!")
|
||||
return None, 0, None
|
||||
|
||||
|
||||
# Subscene CMD
|
||||
@app.on_message(filters.command(["subscene"], COMMAND_HANDLER))
|
||||
@ratelimiter
|
||||
|
|
@ -113,6 +115,7 @@ async def subsceneCMD(client, message):
|
|||
keyboard.row(InlineButton("❌ Close", f"close#{message.from_user.id}"))
|
||||
await editPesan(pesan, subres, disable_web_page_preview=True, reply_markup=keyboard)
|
||||
|
||||
|
||||
# Callback list title
|
||||
@app.on_callback_query(filters.create(lambda _, __, query: "subscenepage#" in query.data))
|
||||
@ratelimiter
|
||||
|
|
@ -142,6 +145,7 @@ async def subpage_callback(client, callback_query):
|
|||
keyboard.row(InlineButton("❌ Close", f"close#{callback_query.from_user.id}"))
|
||||
await editPesan(callback_query.message, subres, disable_web_page_preview=True, reply_markup=keyboard)
|
||||
|
||||
|
||||
# Callback list title
|
||||
@app.on_callback_query(filters.create(lambda _, __, query: "sublist#" in query.data))
|
||||
@ratelimiter
|
||||
|
|
@ -172,6 +176,7 @@ async def subdlpage_callback(client, callback_query):
|
|||
keyboard.row(InlineButton("❌ Close", f"close#{callback_query.from_user.id}"))
|
||||
await editPesan(callback_query.message, subres, disable_web_page_preview=True, reply_markup=keyboard)
|
||||
|
||||
|
||||
# Callback dl subtitle
|
||||
@app.on_callback_query(filters.create(lambda _, __, query: "extractsubs#" in query.data))
|
||||
@ratelimiter
|
||||
|
|
@ -191,6 +196,6 @@ async def dlsub_callback(client, callback_query):
|
|||
scraper = cfscrape.create_scraper()
|
||||
res = await down_page(link)
|
||||
dl = scraper.get(res.get("download_url"))
|
||||
f = open(f"{title}.zip", mode='wb').write(dl.content)
|
||||
f = open(f"{title}.zip", mode="wb").write(dl.content)
|
||||
await callback_query.message.reply_document(f"{title}.zip", caption=f"Title: {res.get('title')}\nIMDb: {res['imdb']}\nAuthor: {res['author_name']}\nRelease Info: ")
|
||||
os.remove(f"{title}.zip")
|
||||
|
|
|
|||
|
|
@ -49,10 +49,7 @@ def split_arr(arr, size: 5):
|
|||
# Terbit21 GetData
|
||||
async def getDataTerbit21(msg, kueri, CurrentPage):
|
||||
if not SCRAP_DICT.get(msg.id):
|
||||
if not kueri:
|
||||
terbitjson = (await http.get("https://yasirapi.eu.org/terbit21")).json()
|
||||
else:
|
||||
terbitjson = (await http.get(f"https://yasirapi.eu.org/terbit21?q={kueri}")).json()
|
||||
terbitjson = (await http.get(f"https://yasirapi.eu.org/terbit21?q={kueri}")).json() if kueri else (await http.get("https://yasirapi.eu.org/terbit21")).json()
|
||||
if not terbitjson.get("result"):
|
||||
await editPesan(msg, "Sorry, could not find any results!")
|
||||
return None, None
|
||||
|
|
@ -68,8 +65,7 @@ async def getDataTerbit21(msg, kueri, CurrentPage):
|
|||
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
|
||||
TerbitRes += f"<b>{c}. <a href='{i['link']}'>{i['judul']}</a></b>\n<b>Category:</b> <code>{i['kategori']}</code>\n"
|
||||
TerbitRes += "\n" if re.search(r"Complete|Ongoing", i["kategori"]) else f"💠 <b><a href='{i['dl']}'>Download</a></b>\n\n"
|
||||
IGNORE_CHAR = "[]"
|
||||
TerbitRes = "".join(i for i in TerbitRes if not i in IGNORE_CHAR)
|
||||
TerbitRes = "".join(i for i in TerbitRes if i not in "[]")
|
||||
return TerbitRes, PageLen
|
||||
except (IndexError, KeyError):
|
||||
await editPesan(msg, "Sorry, could not find any results!")
|
||||
|
|
@ -79,10 +75,7 @@ async def getDataTerbit21(msg, kueri, CurrentPage):
|
|||
# LK21 GetData
|
||||
async def getDatalk21(msg, kueri, CurrentPage):
|
||||
if not SCRAP_DICT.get(msg.id):
|
||||
if not kueri:
|
||||
lk21json = (await http.get("https://yasirapi.eu.org/lk21")).json()
|
||||
else:
|
||||
lk21json = (await http.get(f"https://yasirapi.eu.org/lk21?q={kueri}")).json()
|
||||
lk21json = (await http.get(f"https://yasirapi.eu.org/lk21?q={kueri}")).json() if kueri else (await http.get("https://yasirapi.eu.org/lk21")).json()
|
||||
if not lk21json.get("result"):
|
||||
await editPesan(msg, "Sorry could not find any matching results!")
|
||||
return None, None
|
||||
|
|
@ -98,8 +91,7 @@ async def getDatalk21(msg, kueri, CurrentPage):
|
|||
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
|
||||
lkResult += f"<b>{c}. <a href='{i['link']}'>{i['judul']}</a></b>\n<b>Category:</b> <code>{i['kategori']}</code>\n"
|
||||
lkResult += "\n" if re.search(r"Complete|Ongoing", i["kategori"]) else f"💠 <b><a href='{i['dl']}'>Download</a></b>\n\n"
|
||||
IGNORE_CHAR = "[]"
|
||||
lkResult = "".join(i for i in lkResult if not i in IGNORE_CHAR)
|
||||
lkResult = "".join(i for i in lkResult if i not in "[]")
|
||||
return lkResult, PageLen
|
||||
except (IndexError, KeyError):
|
||||
await editPesan(msg, "Sorry could not find any matching results!")
|
||||
|
|
@ -198,7 +190,7 @@ async def getDataMovieku(msg, kueri, CurrentPage):
|
|||
async def getDataSavefilm21(msg, kueri, CurrentPage, user):
|
||||
if not SCRAP_DICT.get(msg.id):
|
||||
sfdata = []
|
||||
data = await http.get(f"https://193.43.104.235/?s={kueri}", headers=headers)
|
||||
data = await http.get(f"https://savefilm21.pro/?s={kueri}", headers=headers)
|
||||
text = BeautifulSoup(data, "lxml")
|
||||
entry = text.find_all(class_="entry-header")
|
||||
if "Tidak Ditemukan" in entry[0].text:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
import os
|
||||
from asyncio import gather
|
||||
|
||||
from pyrogram import filters
|
||||
|
|
@ -7,7 +6,7 @@ from misskaty import app
|
|||
from misskaty.core.message_utils import *
|
||||
from misskaty.core.decorator.errors import 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
|
||||
|
||||
__MODULE__ = "WebSS"
|
||||
|
|
@ -19,15 +18,16 @@ __HELP__ = """
|
|||
@app.on_message(filters.command(["webss"], COMMAND_HANDLER))
|
||||
@capture_err
|
||||
@ratelimiter
|
||||
async def take_ss(_, m):
|
||||
@use_chat_lang()
|
||||
async def take_ss(_, m, strings):
|
||||
if len(m.command) == 1:
|
||||
return await kirimPesan(m, "Give A Url To Fetch Screenshot.")
|
||||
return await kirimPesan(m, strings("no_url"))
|
||||
url = m.command[1] if m.command[1].startswith("http") else f"https://{m.command[1]}"
|
||||
filename = f"webSS_{m.from_user.id}.png"
|
||||
msg = await m.reply("Capturing screenshot...")
|
||||
msg = await m.reply(strings("wait_str"))
|
||||
try:
|
||||
url = f"https://webss.yasirapi.eu.org/api?url={url}&width=1280&height=720"
|
||||
await gather(*[m.reply_document(url, file_name=filename), m.reply_photo(url)])
|
||||
await hapusPesan(msg)
|
||||
except Exception as e:
|
||||
await editPesan(msg, f"Failed To Take Screenshot. {str(e)}")
|
||||
await editPesan(msg, strings("ss_failed_str").format(err=str(e)))
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ except:
|
|||
|
||||
load_dotenv("config.env", override=True)
|
||||
|
||||
|
||||
def getConfig(name: str):
|
||||
try:
|
||||
return environ[name]
|
||||
except:
|
||||
return ""
|
||||
|
||||
|
||||
# Required ENV
|
||||
try:
|
||||
BOT_TOKEN = getConfig("BOT_TOKEN")
|
||||
|
|
|
|||
15
update.py
15
update.py
|
|
@ -31,19 +31,24 @@ if len(UPSTREAM_REPO_BRANCH) == 0:
|
|||
UPSTREAM_REPO_BRANCH = "master"
|
||||
|
||||
if UPSTREAM_REPO_URL is not None:
|
||||
if os.path.exists('.git'):
|
||||
if os.path.exists(".git"):
|
||||
srun(["rm", "-rf", ".git"])
|
||||
|
||||
update = srun([f"git init -q \
|
||||
update = srun(
|
||||
[
|
||||
f"git init -q \
|
||||
&& git config --global user.email mail@yasir.eu.org \
|
||||
&& git config --global user.name yasirarism \
|
||||
&& git add . \
|
||||
&& git commit -sm update -q \
|
||||
&& git remote add origin {UPSTREAM_REPO_URL} \
|
||||
&& git fetch origin -q \
|
||||
&& git reset --hard origin/{UPSTREAM_REPO_BRANCH} -q"], shell=True)
|
||||
&& git reset --hard origin/{UPSTREAM_REPO_BRANCH} -q"
|
||||
],
|
||||
shell=True,
|
||||
)
|
||||
|
||||
if update.returncode == 0:
|
||||
LOGGER.error('Successfully updated with latest commit from UPSTREAM_REPO')
|
||||
LOGGER.error("Successfully updated with latest commit from UPSTREAM_REPO")
|
||||
else:
|
||||
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!")
|
||||
|
|
|
|||
Loading…
Reference in a new issue