MultiLanguage Support [BETA] (#21)

Pushed to public since i dont know when became stable
This commit is contained in:
yasirarism 2023-03-28 13:15:39 +07:00 committed by GitHub
parent 6ea9bf9d98
commit 3a6c0b424e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1142 additions and 448 deletions

16
database/locale_db.py Normal file
View 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
View file

68
locales/en-US/admins.json Normal file
View 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 🚨"
}

View 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
View file

@ -0,0 +1,3 @@
{
"result": "🎲 The dice stopped at the number: {number}"
}

View file

@ -0,0 +1,3 @@
{
"back_btn": "« Go back"
}

View file

@ -0,0 +1 @@
{}

View 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
View file

@ -0,0 +1,4 @@
{
"language_name": "English",
"language_flag": "🇬🇧"
}

View 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
View 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"
}

View 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."
}

View 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}"
}

View file

@ -0,0 +1 @@
{}

5
locales/en-US/webss.json Normal file
View 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
View 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 🚨"
}

View 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
View file

@ -0,0 +1,3 @@
{
"result": "🎲 Dadu berhenti di angka: {number}"
}

View file

@ -0,0 +1,4 @@
{
"back_btn": "« Kembali",
"no_results": "Tidak ada hasil yang ditemukan."
}

View file

@ -0,0 +1 @@
{}

View 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
View file

@ -0,0 +1,4 @@
{
"language_name": "Indonesia",
"language_flag": "🇮🇩"
}

View 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
View 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"
}

View 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."
}

View 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}"
}

View file

@ -0,0 +1 @@
{}

5
locales/id-ID/webss.json Normal file
View 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
View 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 🚨"
}

View 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
View file

@ -0,0 +1,3 @@
{
"result": "🎲 Dadu mandheg ing nomer: {number}"
}

View file

@ -0,0 +1,4 @@
{
"back_btn": "« Balik Maneh",
"no_results": "Ora ana asil sing ditemokake."
}

View file

@ -0,0 +1 @@
{}

View 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
View file

@ -0,0 +1,4 @@
{
"language_name": "Jawa",
"language_flag": "💫​"
}

View 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
View 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"
}

View 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."
}

View 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}"
}

View file

@ -0,0 +1 @@
{}

5
locales/id-JW/webss.json Normal file
View 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}"
}

View file

@ -10,11 +10,11 @@ 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
handler = handlers.RotatingFileHandler("MissKatyLogs.txt", maxBytes=1024*1024)
handler = handlers.RotatingFileHandler("MissKatyLogs.txt", maxBytes=1024 * 1024)
handler.setLevel(INFO)
logger.addHandler(handler)
getLogger("pyrogram").setLevel(ERROR)
@ -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()

View file

@ -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(" ", "_")

View file

@ -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

View file

@ -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
@ -38,4 +38,4 @@ def ratelimiter(func: Callable) -> Callable:
else:
return await func(client, update)
return decorator
return decorator

View file

@ -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)
@ -42,4 +40,4 @@ class RateLimiter:
self.limiter.try_acquire(userid)
return False
except BucketFullException:
return True
return True

View file

@ -12,4 +12,4 @@ from .time_gap import *
from .ssgen_helper import *
from .tools import *
from .ytdl_helper import *
from .subscene_helper import *
from .subscene_helper import *

View file

@ -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

View 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

View file

@ -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:
@ -224,4 +212,4 @@ async def mediainfo_paste(text: str, title: str) -> str:
html_content = html_builder(title, text)
URL = "https://mediainfo-1-y5870653.deta.app/api"
response = await http.post(URL, json={"content": html_content})
return f"https://mediainfo-1-y5870653.deta.app/{json.loads(response.content)['key']}"
return f"https://mediainfo-1-y5870653.deta.app/{json.loads(response.content)['key']}"

View file

@ -1,43 +1,42 @@
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()
try:
imdb = maindiv.find('div', class_='header').h1.a['href']
except TypeError:
imdb = ""
try:
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_link = f"https://subscene.com{maindiv.find('div', class_='header').ul.find('li', class_='author').a['href']}"
except:
author_link = ""
author_name = "Anonymous"
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()
try:
imdb = maindiv.find("div", class_="header").h1.a["href"]
except TypeError:
imdb = ""
try:
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_link = f"https://subscene.com{maindiv.find('div', class_='header').ul.find('li', class_='author').a['href']}"
except:
author_link = ""
author_name = "Anonymous"
download_url = f"https://subscene.com{maindiv.find('div', class_='header').ul.find('li', class_='clearfix').find('div', class_='download').a['href']}"
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
except:
comments = ""
try:
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:
releases = ""
try:
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")
releases = ""
for i in range(2):
r = release[i].text.strip()
releases = releases + f"\n{r}"
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}
return response
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

View file

@ -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"}

View file

@ -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"
keyboard = ikb({"🚨 Unmute 🚨": f"unmute_{user_id}"})
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:

View file

@ -120,4 +120,4 @@ async def bypass(_, message):
data = wetransfer_bypass(url)
await editPesan(msg, f"{data}\n\n{mention}")
else:
await kirimPesan(message, "Unsupported url..")
await kirimPesan(message, "Unsupported url..")

View file

@ -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)}")

View file

@ -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..",
)
@ -158,37 +156,37 @@ async def evaluation_cmd_t(_, m):
try:
await aexec(cmd, _, m)
except NameError as e:
trace_output = "❌ MISSING VARIABEL:\n"
trace_output += f"{e}"
exc = trace_output
trace_output = "❌ MISSING VARIABEL:\n"
trace_output += f"{e}"
exc = trace_output
except AttributeError as e:
trace_output = "❌ MISSING ATTRIBUTE:\n"
trace_output += f"{e}"
exc = trace_output
except SyntaxError as e:
trace = traceback.format_exc()
splitted = str(trace).split("\n")
end_split = len(splitted)
row_1 = splitted[end_split - 4]
row_2 = splitted[end_split - 3]
row_3 = splitted[end_split - 2]
compiles = row_1 + "\n" + row_2 + "\n" + row_3
trace_output = "⚙️ SYNTAX ERROR:\n"
trace_output += f"{compiles}"
exc = trace_output
trace_output = "❌ MISSING ATTRIBUTE:\n"
trace_output += f"{e}"
exc = trace_output
except SyntaxError:
trace = traceback.format_exc()
splitted = str(trace).split("\n")
end_split = len(splitted)
row_1 = splitted[end_split - 4]
row_2 = splitted[end_split - 3]
row_3 = splitted[end_split - 2]
compiles = row_1 + "\n" + row_2 + "\n" + row_3
trace_output = "⚙️ SYNTAX ERROR:\n"
trace_output += f"{compiles}"
exc = trace_output
except ValueError as e:
trace_output = "🧮 VALUE ERROR:\n"
trace_output += f"{e}"
exc = trace_output
trace_output = "🧮 VALUE ERROR:\n"
trace_output += f"{e}"
exc = trace_output
except Exception as e:
#trace = traceback.format_exc()
""" Periksa apakah error regexnya tertangkap"""
match = re.search(r"Telegram says: .+", str(e))
trace_output = "⚠️ COMMON ERROR:\n"
trace_output += f"{e}"
if match:
trace_output = f"👀 {match[0]}"
exc = trace_output
# trace = traceback.format_exc()
"""Periksa apakah error regexnya tertangkap"""
match = re.search(r"Telegram says: .+", str(e))
trace_output = "⚠️ COMMON ERROR:\n"
trace_output += f"{e}"
if match:
trace_output = f"👀 {match[0]}"
exc = trace_output
stdout = redirected_output.getvalue()
stderr = redirected_error.getvalue()
@ -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"])

View file

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

View file

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

View file

@ -8,7 +8,6 @@
import datetime
import os
import time
import traceback
from asyncio import gather, sleep
from logging import getLogger

View file

@ -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__)

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

View file

@ -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]))

View file

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

View file

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

View file

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

View file

@ -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"))

View file

@ -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

View file

@ -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,21 +17,22 @@ 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):
sdata = []
scraper = cfscrape.create_scraper()
param = {"query": kueri}
r = scraper.post("https://subscene.com/subtitles/searchbytitle", data=param).text
soup = BeautifulSoup(r,"lxml")
r = scraper.post("https://subscene.com/subtitles/searchbytitle", data=param).text
soup = BeautifulSoup(r, "lxml")
lists = soup.find("div", {"class": "search-result"})
entry = lists.find_all("div", {"class":"title"})
entry = lists.find_all("div", {"class": "title"})
# if "Tidak Ditemukan" in entry[0].text:
# 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,14 +54,15 @@ 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")
soup = BeautifulSoup(r, "lxml")
for i in soup.findAll(class_="a1"):
lang = i.find("a").findAll("span")[0].text.strip()
title = i.find("a").findAll("span")[1].text.strip()
@ -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")

View file

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

View file

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

View file

@ -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")
@ -42,7 +44,7 @@ try:
except Exception as e:
LOGGER.error(f"One or more env variables missing! Exiting now.\n{e}")
sys.exit(1)
TZ = environ.get("TZ", "Asia/Jakarta")
COMMAND_HANDLER = environ.get("COMMAND_HANDLER", "! /").split()
SUDO = list(

View file

@ -1,4 +1,4 @@
from subprocess import run as srun
from subprocess import run as srun
import logging, os, requests
from dotenv import load_dotenv
@ -24,26 +24,31 @@ load_dotenv("config.env", override=True)
UPSTREAM_REPO_URL = os.environ.get("UPSTREAM_REPO_URL", "")
if len(UPSTREAM_REPO_URL) == 0:
UPSTREAM_REPO_URL = None
UPSTREAM_REPO_URL = None
UPSTREAM_REPO_BRANCH = os.environ.get("UPSTREAM_REPO_BRANCH", "")
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!")