Beta MultiLang (#26)

This commit is contained in:
yasirarism 2023-04-01 12:06:47 +07:00 committed by GitHub
parent a6136b58e6
commit 83b04d76b5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
50 changed files with 1296 additions and 901 deletions

View file

@ -48,7 +48,9 @@ async def update_karma(chat_id: int, name: str, karma: dict):
async def is_karma_on(chat_id: int) -> bool:
chat = await karmadb.find_one({"chat_id_toggle": chat_id})
return bool(chat)
if not chat:
return True
return False
async def karma_on(chat_id: int):

View file

@ -11,6 +11,6 @@ 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:
async def get_db_lang(chat_id: int) -> str:
ul = await localesdb.find_one({"chat_id": chat_id})
return ul["lang"] if ul else {}

View file

@ -1,7 +1,7 @@
{
"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.",
"private_not_allowed": "This command can't be used in a private chat. If you need any help, please use the /help 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.",

13
locales/en-US/afk.json Normal file
View file

@ -0,0 +1,13 @@
{
"no_channel": "This feature not supported for channel.",
"on_afk_msg_no_r": "**{usr}** [<code>{id}</code>] is back online and was away for {tm}\n\n",
"on_afk_msg_with_r": "**{usr}** [<code>{id}</code>] is back online and was away for {tm}\n\n**Reason:** `{reas}`\n\n",
"is_afk_msg_no_r": "**{usr}** [<code>{id}</code>] is AFK since {tm} ago.\n\n",
"is_afk_msg_with_r": "**{usr}** [<code>{id}</code>] is AFK since {tm} ago.\n\n**Reason:** {reas}\n\n",
"is_online": "**{usr}** [<code>{id}</code>] is back online",
"now_afk": "{usr} [<code>{id}</code>] is now AFK!.",
"afkdel_help": "**Usage:**\n/{cmd} [ENABLE|DISABLE] to enable or disable auto delete message.",
"afkdel_disable": "Disabled auto delete AFK message.",
"afkdel_enable": "Enabled auto delete AFK message in this chat.",
"is_afk": "{usr} [<code>{id}</code>] is AFK!."
}

11
locales/en-US/dev.json Normal file
View file

@ -0,0 +1,11 @@
{
"already_up": "Its already up-to date!",
"up_and_rest": "<b>Updated with default branch, restarting now.</b>",
"cl_btn": "❌ Close",
"no_eval": "__No evaluate message!__",
"run_eval": "<i>Processing eval pyrogram..</i>",
"run_exec": "<i>Processing exec pyrogram..</i>",
"no_cmd": "No command to execute was given.",
"success": "Success",
"no_reply": "No Reply"
}

13
locales/en-US/genss.json Normal file
View file

@ -0,0 +1,13 @@
{
"wait_msg": "Give me some time to process your request!! 😴",
"wait_dl": "<code>Processing, please wait..</code>",
"dl_progress": "Trying to download, please wait..",
"up_progress": "Trying to upload...",
"success_dl_msg": "File has been downloaded to <code>{path}</code>.",
"fail_open": "😟 Sorry! I cannot open the file.",
"limit_dl": "Sorry, download limited to 2GB to reduce flood. You can convert your files to link.",
"err_ssgen": "Failed screenshoot generation.\n\n{exc}",
"up_msg": "☑️ Generation screenshot successfully.\n\n{namma} (<code>{id}</code>)\n#️⃣ #ssgen #id{id}\n\nSS Generate by @{bot_uname}",
"no_reply": "Reply to a Telegram video or document or use direct link after command to generate screenshoot from media!",
"choose_no_ss": "Now choose how many result for screenshot? 🥳.\n\nTotal duration: `{td}` (`{dur} second`)"
}

View file

@ -0,0 +1,17 @@
{
"nmd_disabled": "Nightmode disabled.",
"nmd_not_enabled": "Nightmode isn't enabled in this chat.",
"invalid_time_format": "Invalid time format. Use HH:MM format.",
"invalid_lockdur": "Invalid time duration. Use proper format.\nExample: 6h (for 6 hours), 10m for 10 minutes.",
"schedule_already_on": "Already a schedule is running in this chat. Disable it using `-d` flag.",
"nmd_enable_success": "Successfully enabled nightmode in this chat.\nGroup will be locked at {st} and will be opened after {lockdur} everyday.",
"nmd_cb": "🔖 Hai, Aku {bname} dibuat menggunakan Framework Pyrogram v{ver} dan Python 3.10.\n\nMau buat bot seperti ini? Yuuk belajar di @botindonesia\nOwner: @YasirArisM",
"nmd_off_not_admin": "#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`, since {bname} is not an admin in chat `{chat_id}`",
"nmd_off_not_present": "#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`, since {bname} is not present in chat `{chat_id}`. Removed group from list.",
"nmd_off_err": "#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`\nERROR: `{e}`",
"nmd_off_success": "#NIGHTMODE_HANDLER\n📆 {dt}\n\n☀ Group is Opening.\nWill be closed at {close_at}",
"nmd_on_not_admin": "#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`, since {bname} is not an admin in chat `{chat_id}`",
"nmd_on_not_present": "#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`, since {bname} is not present in chat `{chat_id}`. Removed group from list.",
"nmd_on_err": "#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`\nERROR: `{e}`",
"nmd_on_success": "#NIGHTMODE_HANDLER\n📆 {dt}\n\n🌗 Group is closing.\nWill be opened at {open_at}"
}

View file

@ -0,0 +1,11 @@
{
"newgroup_log": "#NewGroup\nGroup = {jdl}(<code>{id}</code>)\nMembers Count = <code>{c}</code>",
"newuser_log": "#NewUser\nID - <code>{id}</code>\nName - {nm}",
"help_name": "Here is the help for **{mod}**:\n",
"help_txt": "Hello {kamuh}, My name is {bot}.\nI'm a pyrogram bot that developed by kind owner with some useful features.\nYou can look by clicking a button below.\n\nGeneral command are:\n - /start: Start the bot\n - /help: Give this message\n - /setlang: Change bot language [BETA]",
"click_me": "Click Me",
"back_btn": "Back",
"click_btn": "Click on the below button to get help about {nm}",
"pm_detail": "PM Me For More Details.",
"start_msg": "Hi {kamuh}, PM me to know about all my features. You can change bot language in bot using /setlang command but it's still in beta stage."
}

View file

@ -1 +1,18 @@
{}
{
"no_result": "Sorry, i couldn't find any results!",
"no_result_w_query": "Sorry, i could not find query: {kueri}",
"get_data": "⏳ Please wait, getting data from web..",
"cl_btn": "❌ Close",
"back_btn": "↩️ Back",
"dl_text": "⬇️ Download",
"cat_text": "Category",
"quality": "Quality",
"ex_data": "👇 Extract Data ",
"unauth": "This button is not for you..",
"invalid_cb": "Invalid callback data, please send command again..",
"res_scrape": "<b>Scrape result from</b> <code>{link}</code>:\n\n{kl}",
"header_with_query": "<b>#{web} Results For:</b> <code>{kueri}</code>\n\n",
"header_no_query": "<b>#{web} Latest:</b>\n🌀 Use /{cmd} [title] to start search with title.\n\n",
"invalid_cmd_scrape": "Gunakan command /{cmd} <b>[link]</b> untuk scrap link download",
"unsupport_dl_btn": "Some result will not appear in extract button because unsupported link."
}

View file

@ -0,0 +1,13 @@
{
"no_channel": "This feature not supported for channel or anonymous user.",
"no_query": "Please input a query..!",
"no_res": "No result found for `{kweri}`",
"dl_btn": "Download",
"back": "Back",
"yts_msg": "Published {pub}\n\n<b> Duration:</b> {dur}\n<b> Views:</b> {vi}\n<b> Uploader:</b> <a href={clink}>{cname}</a>\n\n",
"invalid_link": "Please input a valid YT-DLP Supported URL",
"err_parse": "Failed parse URL, check logs..",
"wait": "Please wait..",
"unauth": "Not Your Task..",
"endlist": "That's the end of list"
}

View file

@ -1,8 +1,8 @@
{
"no_admin_error": "Anda harus merupakan administrator untuk menggunakan perintah ini.",
"no_admin_error": "Anda harus menjadi 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.",
"private_not_allowed": "Perintah ini tidak dapat digunakan dalam obrolan pribadi, Jika anda membutuhkan bantuan, mohon gunakan perintah /help.",
"purge_no_reply": "Balas ke pesan yang ingin 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.",
@ -13,12 +13,12 @@
"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.",
"demote_self_err": "Saya tidak dapat menurunkan keanggotaan 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?",
"mute_self_err": "Saya tidak dapat membisukan diri sendiri.",
"kick_sudo_err": "Wow, Anda ingin menendang pemilik saya yang spesial?",
"ban_sudo_err": "Wow, Anda ingin mencoba membanned pemilik saya?",
"demote_sudo_err": "Wow, Anda ingin mencoba mendemote 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.",
@ -28,13 +28,13 @@
"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_ban_permission": "Tolong beri saya izin banned untuk membanned 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",
"muted_time": "**Dimute 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.",
"give_unban_user": "Berikan nama pengguna atau balas pesan pengguna untuk membatalkan banned.",
"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",
@ -55,7 +55,7 @@
"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.",
"ch_warn_msg": "Pengguna {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}.",
@ -63,6 +63,6 @@
"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",
"mute_msg": "**Pengguna yang Dimute:** {mention}\n**Dimute Oleh:** {muter}\n",
"rm_warn_btn": "🚨 Hapus Peringatan 🚨"
}

13
locales/id-ID/afk.json Normal file
View file

@ -0,0 +1,13 @@
{
"no_channel": "Fitur ini tidak didukung untuk channel.",
"on_afk_msg_no_r": "**{usr}** [<code>{id}</code>] kembali online dan pergi selama {tm}\n\n",
"on_afk_msg_with_r": "**{usr}** [<code>{id}</code>] kembali online dan pergi untuk {tm}\n\n**Alasan:** `{reas}`\n\n",
"is_afk_msg_no_r": "**{usr}** [<code>{id}</code>] telah AFK sejak {tm} yang lalu.\n\n",
"is_afk_msg_with_r": "**{usr}** [<code>{id}</code>] telah AFK sejak {tm} yang lalu.\n\n**Alasan:** {reas}\n\n" ,
"is_online": "**{usr}** [<code>{id}</code>] kembali online",
"now_afk": "{usr} [<code>{id}</code>] sekarang AFK!.",
"afkdel_help": "**Penggunaan:**\n/{cmd} [ENABLE|DISABLE] untuk mengaktifkan atau menonaktifkan hapus pesan AFK secara otomatis.",
"afkdel_disable": "Penghapusan otomatis pesan AFK dinonaktifkan.",
"afkdel_enable": "Penghapusan otomatis pesan AFK di obrolan ini diaktifkan.",
"is_afk": "{usr} [<code>{id}</code>] sedang AFK!."
}

View file

@ -1,5 +1,5 @@
{
"no_question": "Harap gunakan perintah <code>/{cmd} [question]</code> untuk mengajukan pertanyaan Anda.",
"find_answers_str": "Tunggu sebentar untuk mencari jawaban Anda..",
"no_question": "Harap gunakan perintah <code>/{cmd} [question]</code> untuk mengajukan pertanyaan Anda menggunakan OpenAI.",
"find_answers_str": "Sedang mencari jawaban terbaik buat Anda..",
"answers_too_long": "Pertanyaan untuk jawaban Anda telah melampaui batas teks TG, periksa tautan ini untuk melihatnya.\n\n{answerlink}"
}

11
locales/id-ID/dev.json Normal file
View file

@ -0,0 +1,11 @@
{
"already_up": "Sudah paling update!",
"up_and_rest": "<b>Diperbarui dengan branch default, dimulai ulang sekarang.</b>",
"cl_btn": "❌ Tutup",
"no_eval": "__Tidak ada pesan eval!__",
"run_eval": "<i>Memproses pyrogram eval..</i>",
"run_exec": "<i>Memproses pyrogram eksekutif..</i>",
"no_cmd": "Tidak ada perintah untuk dieksekusi.",
"sukses": "Sukses",
"no_reply": "Tidak ada balasan"
}

13
locales/id-ID/genss.json Normal file
View file

@ -0,0 +1,13 @@
{
"wait_msg": "Beri saya waktu untuk memproses permintaan Anda!! 😴",
"wait_dl": "<code>Sedang diproses, harap tunggu..</code>",
"dl_progress": "Mencoba mengunduh, harap tunggu..",
"up_progress": "Mencoba mengunggah...",
"success_dl_msg": "Berkas telah diunduh ke <code>{path}</code>.",
"fail_open": "😟 Maaf! Saya tidak dapat membuka file.",
"limit_dl": "Maaf, unduh terbatas hingga 2GB untuk mengurangi flood. Anda dapat mengkonversi file Anda menjadi tautan.",
"err_ssgen": "Pembuatan screenshot gagal.\n\n{exc}",
"up_msg": "☑️ Pembuatan screenshot berhasil.\n\n{namma} (<code>{id}</code>)\n#️⃣ #ssgen #id{id}\n\nSS Dibuat oleh @{bot_uname} ",
"no_reply": "Balas video atau dokumen Telegram atau gunakan tautan langsung setelah perintah untuk membuat screenshot dari media!",
"choose_no_ss": "Sekarang pilih berapa hasil screenshot? 🥳.\n\nTotal durasi: `{td}` (`{dur} detik`)"
}

View file

@ -1,5 +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."
"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, buka repo misskaty di github."
}

View file

@ -3,9 +3,9 @@
"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_limit_exceeded": "Maaf, unduh dibatasi hingga 2GB untuk mengurangi flood. 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"
"capt_media": " Hasil mediainfo anda..\n\n**Diminta Oleh:** {ment}",
"viweb": "💬 Buka di Web"
}

View file

@ -0,0 +1,17 @@
{
"nmd_disabled": "Mode malam dinonaktifkan.",
"nmd_not_enabled": "Mode malam tidak diaktifkan di obrolan ini.",
"invalid_time_format": "Format waktu tidak sah. Gunakan format HH:MM.",
"invalid_lockdur": "Durasi waktu tidak valid. Gunakan format yang tepat.\nContoh: 6j (selama 6 jam), 10m selama 10 menit.",
"schedule_already_on": "Sudah ada jadwal yang berjalan di obrolan ini. Nonaktifkan menggunakan tanda `-d`.",
"nmd_enable_success": "Berhasil mengaktifkan mode malam dalam obrolan ini.\nGrup akan dikunci pada {st} dan akan dibuka setelah {lockdur} setiap hari.",
"nmd_cb": "🔖 Hai, Saya {bname} dibuat menggunakan Framework Pyrogram v{ver} dan Python 3.10.\n\nMau buat bot seperti ini? Yuuk belajar di @botindonesia\nOwner: @YasirArisM",
"nmd_off_not_admin": "#NIGHTMODE_FAIL\nGagal mematikan mode malam di `{chat_id}`, karena {bname} bukan admin di obrolan `{chat_id}`",
"nmd_off_not_present": "#NIGHTMODE_FAIL\nGagal mematikan mode malam di `{chat_id}`, karena {bname} tidak ada di obrolan `{chat_id}`. Menghapus grup dari daftar.",
"nmd_off_err": "#NIGHTMODE_FAIL\nGagal mematikan mode malam di `{chat_id}`\nERROR: `{e}`",
"nmd_off_success": "#NIGHTMODE_HANDLER\n📆 {dt}\n\n☀ Grup sedang dibuka.\nAkan ditutup pada {close_at}",
"nmd_on_not_admin": "#NIGHTMODE_FAIL\nGagal mengaktifkan mode malam di `{chat_id}`, karena {bname} bukan admin di obrolan `{chat_id}`",
"nmd_on_not_present": "#NIGHTMODE_FAIL\nGagal mengaktifkan mode malam di `{chat_id}`, karena {bname} tidak ada di obrolan `{chat_id}`. Grup dihapus dari daftar.",
"nmd_on_err": "#NIGHTMODE_FAIL\nGagal mengaktifkan mode malam di `{chat_id}`\nERROR: `{e}`",
"nmd_on_success": "#NIGHTMODE_HANDLER\n📆 {dt}\n\n🌗 Grup ditutup.\nAkan dibuka pada {open_at}"
}

View file

@ -0,0 +1,11 @@
{
"newgroup_log": "#NewGroup\nGroup = {jdl}(<code>{id}</code>)\nJumlah Anggota = <code>{c}</code>",
"newuser_log": "#PenggunaBaru\nID - <kode>{id}</code>\nNama - {nm}",
"help_name": "Ini bantuan untuk **{mod}**:\n",
"help_txt": "Halo {kamuh}, Nama saya {bot}.\nSaya adalah bot pyrogram yang dikembangkan oleh pemilik yang baik hati dengan beberapa fitur berguna.\nAnda dapat melihat dengan mengeklik tombol di bawah.\n\nPerintah umum adalah :\n - /start: Mulai bot\n - /help: Berikan pesan ini\n - /setlang: Ubah bahasa bot [BETA]",
"click_me": "Klik Saya",
"back_btn": "Kembali",
"click_btn": "Klik tombol di bawah untuk mendapatkan bantuan tentang {nm}",
"pm_detail": "PM Saya Untuk Detail Lebih Lanjut.",
"start_msg": "Hai {kamuh}, PM saya untuk mengetahui semua fitur saya. Anda dapat mengubah bahasa bot di bot menggunakan perintah /setlang tetapi ini masih dalam tahap beta."
}

View file

@ -14,6 +14,6 @@
"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",
"viewpack": "👀 Lihat Paket",
"kang_success": "<b>Stiker berhasil dicuri!</b>\n<b>Emoji:</b> {emot}"
}

View file

@ -1 +1,18 @@
{}
{
"no_result": "Maaf, saya tidak dapat menemukan hasil apa pun!",
"no_result_w_query": "Maaf, saya tidak dapat menemukan kueri: {kueri}",
"get_data": "⏳ Mohon tunggu, mengambil data dari web..",
"cl_btn": "❌ Tutup",
"back_btn": "↩️ Kembali",
"dl_text": "⬇️ Unduh",
"cat_text": "Kategori",
"kualitas": "Kualitas",
"ex_data": "👇 Ekstrak Data",
"unauth": "Tombol ini bukan untuk Anda..",
"invalid_cb": "Data callback tidak valid, silakan kirim perintah lagi..",
"res_scrape": "<b>Hasil Scrape dari</b> <code>{link}</code>:\n\n{kl}",
"header_with_query": "<b>Hasil Pencarian #{web} Untuk:</b> <code>{kueri}</code>\n\n",
"header_no_query": "<b>#{web} Terbaru:</b>\n🌀 Gunakan /{cmd} [judul] untuk memulai pencarian dengan judul.\n\n",
"invalid_cmd_scrape": "Gunakan perintah /{cmd} <b>[tautan]</b> untuk mengambil link unduhan.",
"unsupport_dl_btn": "Beberapa hasil tidak akan muncul di tombol ekstrak karena tautan tidak didukung."
}

View file

@ -0,0 +1,13 @@
{
"no_channel": "Fitur ini tidak didukung untuk channel atau pengguna anonim.",
"no_query": "Silakan kirim link yang mau diunduh..!",
"no_res": "Tidak ada hasil yang ditemukan untuk `{kweri}`",
"dl_btn": "Unduh",
"kembali": "kembali",
"yts_msg": "Dipublikasikan {pub}\n\n<b> Durasi:</b> {dur}\n<b> Penayangan:</b> {vi}\n<b> Pengunggah:< /b> <a href={clink}>{cname}</a>\n\n",
"invalid_link": "Masukkan URL yang Didukung YT-DLP yang valid",
"err_parse": "Gagal menguraikan URL, periksa log..",
"tunggu": "Harap tunggu..",
"unauth": "Bukan Tugas Anda..",
"endlist": "Itu adalah akhir dari daftar"
}

View file

@ -1,21 +1,21 @@
{
"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>.",
"no_permission_error": "Ngapunten, nanging sampeyan ora duwe izin sing dibutuhake kanggo nindakake perintah iki. Izin sing ilang: {permissions}",
"private_not_allowed": "Perintah iki ora bisa digunakake ing obrolan pribadi, Yen sampeyan butuh bantuan, mohon nggunakake perintah /help.",
"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.",
"no_delete_perm": "Tulung aku kei izin 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.",
"demote_self_err": "Aku ora bisa mudhun dhewe.",
"warn_self_err": "Aku ora bisa ngelekake awakku dhewe.",
"mute_self_err": "Aku ora bisa bisu.",
"mute_self_err": "Aku ora bisa bisu awakku dhewe.",
"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?",
@ -51,7 +51,7 @@
"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!.",
"pin_no_perm": "Tulung wenehi pin izin 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.",

13
locales/id-JW/afk.json Normal file
View file

@ -0,0 +1,13 @@
{
"no_channel": "Fitur iki ora didhukung kanggo channel.",
"on_afk_msg_no_r": "**{usr}** [<code>{id}</code>] wis online maneh lan ora ana ing {tm}\n\n",
"on_afk_msg_with_r": "**{usr}** [<code>{id}</code>] wis online maneh lan ora ana {tm}\n\n**Alesan:** `{reas}`\n\n",
"is_afk_msg_no_r": "**{usr}** [<code>{id}</code>] iku AFK wiwit {tm} kepungkur.\n\n",
"is_afk_msg_with_r": "**{usr}** [<code>{id}</code>] iku AFK wiwit {tm} kepungkur.\n\n**Alesan:** {reas}\n\n" ,
"is_online": "**{usr}** [<code>{id}</code>] wis online maneh",
"now_afk": "{usr} [<code>{id}</code>] saiki dadi AFK!.",
"afkdel_help": "**Panganggone:**\n/{cmd} [ENABLE|DISABLE] kanggo ngaktifake utawa mateni pesen otomatis mbusak.",
"afkdel_disable": "Mbusak pesen AFK otomatis dipateni.",
"afkdel_enable": "Mbusak pesen AFK otomatis ing obrolan iki diaktifake.",
"is_afk": "{usr} [<code>{id}</code>] iku AFK!."
}

View file

@ -1,5 +1,5 @@
{
"no_question": "Tulung gunakake printah <code>/{cmd} [pitakon]</code> kanggo takon.",
"find_answers_str": "Ngenteni sedhela goleki jawabanmu..",
"no_question": "Tulung gunakake printah <code>/{cmd} [pitakon]</code> kanggo takon nganggo fitur OpenAI.",
"find_answers_str": "Lagi goleki jawaban paling apik kanggo sampeyan..",
"answers_too_long": "Pitakonan kanggo jawaban sampeyan wis ngluwihi wates teks TG, priksa pranala iki kanggo ndeleng.\n\n{answerlink}"
}

11
locales/id-JW/dev.json Normal file
View file

@ -0,0 +1,11 @@
{
"already_up": "Wis up-to-date!",
"up_and_rest": "<b>Dianyari nganggo branch standar, diwiwiti maneh saiki.</b>",
"cl_btn": "❌ Tutup",
"no_eval": "__Ora ana pesen eval!__",
"run_eval": "<i>Ngolah pyrogram eval..</i>",
"run_exec": "<i>Ngolah pyrogram exec..</i>",
"no_cmd": "Ora ana prentah kanggo nglakokaké.",
"success": "Sukses",
"no_reply": "Ora Wangsulan"
}

13
locales/id-JW/genss.json Normal file
View file

@ -0,0 +1,13 @@
{
"wait_msg": "Wenehi wektu kanggo ngolah panjalukmu!! 😴",
"wait_dl": "<code>Lagi diproses, mangga ngenteni..</code>",
"dl_progress": "Nyoba ngundhuh, mangga ngenteni..",
"up_progress": "Nyoba ngunggah...",
"success_dl_msg": "Berkas wis diundhuh menyang <code>{path}</code>.",
"fail_open": "😟 Nuwun sewu! Aku ora bisa mbukak file.",
"limit_dl": "Nuwun sewu, download dibatesi nganti 2GB kanggo nyuda flood. Sampeyan bisa ngowahi file dadi link.",
"err_ssgen": "Gagal nggawe screenshoot.\n\n{exc}",
"up_msg": "☑️ Screenshot generasi kasil.\n\n{namma} (<code>{id}</code>)\n#️⃣ #ssgen #id{id}\n\nSS Digawe kalo @{bot_uname} ",
"no_reply": "Bales menyang video utawa dokumen Telegram utawa gunakake link langsung sawise printah kanggo ngasilake screenshot saka media!",
"choose_no_ss": "Saiki pilih pira asil kanggo screenshot? 🥳.\n\nTotal durasi: `{td}` (`{dur} second`)"
}

View file

@ -1,11 +1,11 @@
{
"processing_text": "`Pengolahan, wektu total adhedhasar ukuran berkas panjenengan...`",
"wait_msg": "`Mohon tunggu sejenak...`",
"wait_msg": "`Tulung enteni sedhela...`",
"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_limit_exceeded": "Nuwun sewu, download diwatesi 2GB kanggo nyuda flood. 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}",
"capt_media": " Hasil mediainfo sampeyan..\n\n**Panjalukan Saka:** {ment}",
"viweb": "💬 Bukak Web"
}

View file

@ -0,0 +1,17 @@
{
"nmd_disabled": "Mode wengi dipateni.",
"nmd_not_enabled": "Mode wengi ora diaktifake ing obrolan iki.",
"invalid_time_format": "Format wektu ora valid. Gunakake format HH:MM.",
"invalid_lockdur": "Suwene wektu ora bener. Gunakake format sing bener.\nConto: 6h (6 jam), 10m kanggo 10 menit.",
"schedule_already_on": "Wis ana jadwal ing obrolan iki. Pateni nganggo gendéra `-d`.",
"nmd_enable_success": "Kasil ngaktifake mode wengi ing obrolan iki.\nGrup bakal dikunci ing {st} lan bakal dibukak sawise {lockdur} saben dina.",
"nmd_cb": "🔖 Hai, Aku {bname} digawe nganggo Framework Pyrogram v{ver} lan Python 3.10.\n\nMau gawe bot kaya iki? Yuuk belajar di @botindonesia\nOwner: @YasirArisM",
"nmd_off_not_admin": "#NIGHTMODE_FAIL\nGagal mateni nightmode ing `{chat_id}`, amarga {bname} dudu admin ing chat `{chat_id}`",
"nmd_off_not_present": "#NIGHTMODE_FAIL\nGagal mateni nightmode ing `{chat_id}`, amarga {bname} ora ana ing chat `{chat_id}`. Dibusak grup saka dhaptar.",
"nmd_off_err": "#NIGHTMODE_FAIL\nGagal mateni nightmode ing `{chat_id}`\nERROR: `{e}`",
"nmd_off_success": "#NIGHTMODE_HANDLER\n📆 {dt}\n\n☀ Grup dibukak.\nBakal ditutup jam {close_at}",
"nmd_on_not_admin": "#NIGHTMODE_FAIL\nGagal ngaktifake mode wengi ing `{chat_id}`, amarga {bname} dudu admin ing chat `{chat_id}`",
"nmd_on_not_present": "#NIGHTMODE_FAIL\nGagal ngaktifake mode wengi ing `{chat_id}`, amarga {bname} ora ana ing obrolan `{chat_id}`. Grup dibusak saka dhaptar.",
"nmd_on_err": "#NIGHTMODE_FAIL\nGagal ngaktifake mode wengi ing `{chat_id}`\nERROR: `{e}`",
"nmd_on_success": "#NIGHTMODE_HANDLER\n📆 {dt}\n\n🌗 Grup ditutup.\nBakal dibukak ing {open_at}"
}

View file

@ -0,0 +1,11 @@
{
"newgroup_log": "#NewGroup\nGroup = {jdl}(<code>{id}</code>)\nJumlah Anggota = <code>{c}</code>",
"newuser_log": "#NewUser\nID - <code>{id}</code>\nJeneng - {nm}",
"help_name": "Iki bantuan kanggo **{mod}**:\n",
"help_txt": "Halo {kamuh}, jenengku {bot}.\nAku bot pyrogram sing dikembangake dening pemilik apik karo sawetara fitur migunani.\nSampeyan bisa ndeleng kanthi ngeklik tombol ing ngisor iki.\n\nPrentah umum yaiku :\n - /start: Miwiti bot\n - /help: Wenehi pesen iki\n - /setlang: Ganti basa bot [BETA]",
"click_me": "Klik Aku",
"back_btn": "Mbalik",
"click_btn": "Klik tombol ing ngisor iki kanggo njaluk bantuan babagan {nm}",
"pm_detail": "PM Aku Kanggo Rincian Liyane.",
"start_msg": "Halo {kamuh}, PM aku kanggo ngerti kabeh fiturku. Sampeyan bisa ngganti basa bot ing bot nggunakake perintah /setlang nanging isih ing tahap beta."
}

View file

@ -14,6 +14,6 @@
"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",
"viewpack": "👀 Deleng Paket",
"kang_success": "<b>Stiker kasil dicolong!</b>\n<b>Emoji:</b> {emot}"
}

View file

@ -1 +1,18 @@
{}
{
"no_result": "Nuwun sewu, kula mboten nemu kasil!",
"no_result_w_query": "Nuwun sewu, kula mboten saged manggihaken pitakon: {kueri}",
"get_data": "⏳ Mangga dienteni, lagi njupuk data saka web..",
"cl_btn": "❌ Tutup",
"back_btn": "↩️ Mbalik",
"dl_text": "⬇️ Unduh",
"cat_text": "💠 Kategori",
"kualitas": "Kualitas",
"ex_data": "👇 Ekstrak Data ",
"unauth": "Tombol iki dudu kanggo sampeyan..",
"invalid_cb": "Data callback ora valid, kirim printah maneh..",
"res_scrape": "<b>Asil scrape saka</b> <kode>{link}</code>:\n\n{kl}",
"header_with_query": "<b>Asil Nggoleki #{web} Kanggo:</b> <code>{kueri}</code>\n\n",
"header_no_query": "<b>#{web} Paling anyar:</b>\n🌀 Gunakake /{cmd} [judhul] kanggo miwiti nggoleki kanthi judhul.\n\n",
"invalid_cmd_scrape": "Gunakake prentah /{cmd} <b>[pranala]</b> kanggo ngunduh pranala kethokan",
"unsupport_dl_btn": "Sawetara asil ora bakal katon ing tombol ekstrak amarga pranala ora didhukung."
}

View file

@ -0,0 +1,13 @@
{
"no_channel": "Fitur iki ora didhukung kanggo channel utawa pangguna anonim.",
"no_query": "Mangga lebokna url sing kepengen mbok unduh..!",
"no_res": "Ora ana asil kanggo `{kweri}`",
"dl_btn": "Ngunduh",
"back": "Mbalik",
"yts_msg": "Diterbitake {pub}\n\n<b> Duration:</b> {dur}\n<b> Ndeleng:</b> {vi}\n<b> Uploader:< /b> <a href={clink}>{cname}</a>\n\n",
"invalid_link": "Mangga lebokna URL Dhukungan YT-DLP sing valid",
"err_parse": "Gagal ngurai URL, mriksa log..",
"ngenteni": "Tulung ngenteni..",
"unauth": "Ora Tugasmu..",
"endlist": "Iku pungkasan dhaptar"
}

View file

@ -7,17 +7,14 @@
"""
import asyncio
import importlib
import re
import os
import pickle
import traceback
from logging import getLogger
from pyrogram import __version__, filters, idle
from pyrogram import __version__, idle
from pyrogram.raw.all import layer
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.users_chats_db import db
from misskaty import (
BOT_NAME,
BOT_USERNAME,
@ -26,12 +23,9 @@ from misskaty import (
app,
scheduler
)
from misskaty.core.message_utils import *
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import bot_sys_stats, paginate_modules
from misskaty.plugins import ALL_MODULES
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO
from utils import auto_clean, temp
from misskaty.vars import SUDO
from utils import auto_clean
LOGGER = getLogger(__name__)
loop = asyncio.get_event_loop()
@ -80,293 +74,6 @@ async def start_bot():
asyncio.create_task(auto_clean())
await idle()
home_keyboard_pm = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(text="Commands ❓", callback_data="bot_commands"),
InlineKeyboardButton(
text="Source Code 🛠",
url="https://github.com/yasirarism/MissKatyPyro",
),
],
[
InlineKeyboardButton(
text="System Stats 🖥",
callback_data="stats_callback",
),
InlineKeyboardButton(text="Dev 👨", url="https://t.me/YasirArisM"),
],
[
InlineKeyboardButton(
text="Add Me To Your Group 🎉",
url=f"http://t.me/{BOT_USERNAME}?startgroup=new",
)
],
]
)
home_text_pm = f"Hey there! My name is {BOT_NAME}. I have many useful features for you, feel free to add me to your group.\n\nIf you want give coffee to my owner you can send /donate command for more info."
keyboard = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(text="Help ❓", url=f"t.me/{BOT_USERNAME}?start=help"),
InlineKeyboardButton(
text="Source Code <20>",
url="https://github.com/yasirarism/MissKatyPyro",
),
],
[
InlineKeyboardButton(
text="System Stats 💻",
callback_data="stats_callback",
),
InlineKeyboardButton(text="Dev 👨", url="https://t.me/YasirArisM"),
],
]
)
@app.on_message(filters.command("start", COMMAND_HANDLER))
@ratelimiter
async def start(_, message):
if not message.from_user: return
if message.chat.type.value != "private":
if not await db.get_chat(message.chat.id):
total = await app.get_chat_members_count(message.chat.id)
await app.send_message(
LOG_CHANNEL,
f"#NewGroup\nGroup = {message.chat.title}(<code>{message.chat.id}</code>)\nMembers Count = <code>{total}</code>\nAdded by - Unknown",
)
await db.add_chat(message.chat.id, message.chat.title)
nama = (
message.from_user.mention
if message.from_user
else message.sender_chat.title
)
return await message.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=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):
await db.add_user(message.from_user.id, message.from_user.first_name)
await app.send_message(
LOG_CHANNEL,
f"#NewUser\nID - <code>{message.from_user.id}</code>\nName - {message.from_user.mention}",
)
if len(message.text.split()) > 1:
name = (message.text.split(None, 1)[1]).lower()
if "_" in name:
module = name.split("_", 1)[1]
text = (
f"Here is the help for **{HELPABLE[module].__MODULE__}**:\n"
+ HELPABLE[module].__HELP__
)
await kirimPesan(message, text, disable_web_page_preview=True)
elif name == "help":
text, keyb = await help_parser(message.from_user.first_name)
await kirimPesan(
message,
text,
reply_markup=keyb,
)
else:
await message.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=home_text_pm,
reply_markup=home_keyboard_pm,
)
@app.on_callback_query(filters.regex("bot_commands"))
@ratelimiter
async def commands_callbacc(_, CallbackQuery):
text, keyboard = await help_parser(CallbackQuery.from_user.mention)
await app.send_message(
CallbackQuery.message.chat.id,
text=text,
reply_markup=keyboard,
)
await hapusPesan(CallbackQuery.message)
@app.on_callback_query(filters.regex("stats_callback"))
@ratelimiter
async def stats_callbacc(_, CallbackQuery):
text = await bot_sys_stats()
await app.answer_callback_query(CallbackQuery.id, text, show_alert=True)
@app.on_message(filters.command("help", COMMAND_HANDLER))
@ratelimiter
async def help_command(_, message):
if not message.from_user: return
if message.chat.type.value != "private":
if not await db.get_chat(message.chat.id):
total = await app.get_chat_members_count(message.chat.id)
await app.send_message(
LOG_CHANNEL,
f"#NewGroup\nGroup = {message.chat.title}(<code>{message.chat.id}</code>)\nMembers Count = <code>{total}</code>\nAdded by - Unknown",
)
await db.add_chat(message.chat.id, message.chat.title)
if len(message.command) >= 2:
name = (message.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE:
key = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text="Click here",
url=f"t.me/{BOT_USERNAME}?start=help_{name}",
)
],
]
)
await kirimPesan(
message,
f"Click on the below button to get help about {name}",
reply_markup=key,
)
else:
await kirimPesan(message, "PM Me For More Details.", reply_markup=keyboard)
else:
await kirimPesan(message, "Pm Me For More Details.", reply_markup=keyboard)
else:
if not await db.is_user_exist(message.from_user.id):
await db.add_user(message.from_user.id, message.from_user.first_name)
await app.send_message(
LOG_CHANNEL,
f"#NewUser\nID - <code>{message.from_user.id}</code>\nName - {message.from_user.mention}",
)
if len(message.command) >= 2:
name = (message.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE:
text = (
f"Here is the help for **{HELPABLE[name].__MODULE__}**:\n"
+ HELPABLE[name].__HELP__
)
await kirimPesan(message, text, disable_web_page_preview=True)
else:
text, help_keyboard = await help_parser(message.from_user.first_name)
await kirimPesan(
message,
text,
reply_markup=help_keyboard,
disable_web_page_preview=True,
)
else:
text, help_keyboard = await help_parser(message.from_user.first_name)
await kirimPesan(
message, text, reply_markup=help_keyboard, disable_web_page_preview=True
)
return
async def help_parser(name, keyboard=None):
if not keyboard:
keyboard = InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help"))
return (
"""Hello {first_name}, My name is {bot_name}.
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.
""".format(
first_name=name,
bot_name="MissKaty",
),
keyboard,
)
@app.on_callback_query(filters.regex(r"help_(.*?)"))
@ratelimiter
async def help_button(client, query):
home_match = re.match(r"help_home\((.+?)\)", query.data)
mod_match = re.match(r"help_module\((.+?)\)", query.data)
prev_match = re.match(r"help_prev\((.+?)\)", query.data)
next_match = re.match(r"help_next\((.+?)\)", query.data)
back_match = re.match(r"help_back", query.data)
create_match = re.match(r"help_create", query.data)
top_text = f"""
Hello {query.from_user.first_name}, My name is MissKaty.
I'm a bot with some usefule features.
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(" ", "_")
text = f"Here is the help for **{HELPABLE[module].__MODULE__}**:\n{HELPABLE[module].__HELP__}"
await editPesan(
query.message,
text=text,
reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton("back", callback_data="help_back")]]
),
disable_web_page_preview=True,
)
elif home_match:
await app.send_message(
query.from_user.id,
text=home_text_pm,
reply_markup=home_keyboard_pm,
)
await hapusPesan(query.message)
elif prev_match:
curr_page = int(prev_match[1])
await editPesan(
query.message,
text=top_text,
reply_markup=InlineKeyboardMarkup(
paginate_modules(curr_page - 1, HELPABLE, "help")
),
disable_web_page_preview=True,
)
elif next_match:
next_page = int(next_match[1])
await editPesan(
query.message,
text=top_text,
reply_markup=InlineKeyboardMarkup(
paginate_modules(next_page + 1, HELPABLE, "help")
),
disable_web_page_preview=True,
)
elif back_match:
await editPesan(
query.message,
text=top_text,
reply_markup=InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help")),
disable_web_page_preview=True,
)
elif create_match:
text, keyboard = await help_parser(query)
await editPesan(
query.message,
text=text,
reply_markup=keyboard,
disable_web_page_preview=True,
)
return await client.answer_callback_query(query.id)
if __name__ == "__main__":
try:
loop.run_until_complete(start_bot())

View file

@ -39,6 +39,47 @@ async def member_permissions(chat_id: int, user_id: int):
perms.append("can_manage_video_chats")
return perms
async def check_perms(
message: Union[CallbackQuery, Message],
permissions: Optional[Union[list, str]],
complain_missing_perms: bool,
strings,
) -> bool:
if isinstance(message, CallbackQuery):
sender = partial(message.answer, show_alert=True)
chat = message.message.chat
else:
sender = message.reply_text
chat = message.chat
# TODO: Cache all admin permissions in db.
user = await chat.get_member(message.from_user.id)
if user.status == enums.ChatMemberStatus.OWNER:
return True
# No permissions specified, accept being an admin.
if not permissions and user.status == enums.ChatMemberStatus.ADMINISTRATOR:
return True
if user.status != enums.ChatMemberStatus.ADMINISTRATOR:
if complain_missing_perms:
await sender(strings("no_admin_error"))
return False
if isinstance(permissions, str):
permissions = [permissions]
missing_perms = [
permission
for permission in permissions
if not getattr(user.privileges, permission)
]
if not missing_perms:
return True
if complain_missing_perms:
await sender(
strings("no_permission_error").format(permissions=", ".join(missing_perms))
)
return False
async def check_perms(
message: Union[CallbackQuery, Message],
@ -148,7 +189,6 @@ def adminsOnly(permission):
return subFunc
def require_admin(
permissions: Union[list, str] = None,
allow_in_private: bool = False,

View file

@ -79,7 +79,7 @@ async def get_lang(message) -> str:
else:
raise TypeError(f"Update type '{message.__name__}' is not supported.")
lang = await get_db_lang(chat.id, chat.type)
lang = await get_db_lang(chat.id)
if chat.type == ChatType.PRIVATE:
lang = lang or message.from_user.language_code or default_language

View file

@ -365,32 +365,28 @@ async def promoteFunc(client, message, strings):
return await message.reply_text(strings("no_promote_perm"))
if message.command[0][0] == "f":
await message.chat.promote_member(
user_id,
ChatPrivileges(
can_change_info=bot.can_change_info,
can_invite_users=bot.can_invite_users,
can_delete_messages=bot.can_delete_messages,
can_restrict_members=bot.can_restrict_members,
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,
),
user_id=user_id,
can_change_info=bot.privileges.can_change_info,
can_invite_users=bot.privileges.can_invite_users,
can_delete_messages=bot.privileges.can_delete_messages,
can_restrict_members=bot.privileges.can_restrict_members,
can_pin_messages=bot.privileges.can_pin_messages,
can_promote_members=bot.privileges.can_promote_members,
can_manage_chat=bot.privileges.can_manage_chat,
can_manage_video_chats=bot.privileges.can_manage_video_chats,
)
return await message.reply_text(strings("full_promote").format(umention=umention))
await message.chat.promote_member(
user_id,
ChatPrivileges(
can_change_info=False,
can_invite_users=bot.can_invite_users,
can_delete_messages=bot.can_delete_messages,
can_restrict_members=False,
can_pin_messages=False,
can_promote_members=False,
can_manage_chat=bot.can_manage_chat,
can_manage_voice_chats=bot.can_manage_voice_chats,
),
user_id=user_id,
can_change_info=False,
can_invite_users=bot.privileges.can_invite_users,
can_delete_messages=bot.privileges.can_delete_messages,
can_restrict_members=bot.privileges.can_restrict_members,
can_pin_messages=bot.privileges.can_pin_messages,
can_promote_members=False,
can_manage_chat=bot.privileges.can_manage_chat,
can_manage_video_chats=bot.privileges.can_manage_video_chats,
)
await message.reply_text(strings("normal_promote").format(umention=umention))
@ -410,7 +406,17 @@ async def demote(client, message, strings):
return await message.reply_text(strings("demote_self_err"))
if user_id in SUDO:
return await message.reply_text(strings("demote_sudo_err"))
await message.chat.promote_member(user_id=user_id)
await message.chat.promote_member(
user_id=user_id,
can_change_info=False,
can_invite_users=False,
can_delete_messages=False,
can_restrict_members=False,
can_pin_messages=False,
can_promote_members=False,
can_manage_chat=False,
can_manage_video_chats=False,
)
umention = (await app.get_users(user_id)).mention
await message.reply_text(f"Demoted! {umention}")
@ -507,8 +513,8 @@ async def unmute(_, message, strings):
if not user_id:
return await message.reply_text(strings("user_not_found"))
await message.chat.unban_member(user_id)
(await app.get_users(user_id)).mention
await message.reply_text(strings("unmute_msg"))
umention = (await app.get_users(user_id)).mention
await message.reply_text(strings("unmute_msg").format(umention=umention))
@app.on_message(filters.command(["warn", "dwarn"], COMMAND_HANDLER) & filters.group)

View file

@ -10,8 +10,9 @@
# Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import time
import re
from pyrogram import filters
from pyrogram import filters, enums
from database.afk_db import add_afk, cleanmode_off, cleanmode_on, is_afk, remove_afk
from misskaty import app
@ -20,6 +21,7 @@ from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import kirimPesan
from misskaty.helper import get_readable_time2
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
from utils import put_cleanmode
@ -34,9 +36,10 @@ Just type something in group to remove AFK Status."""
@capture_err
@app.on_message(filters.command(["afk"], COMMAND_HANDLER))
@ratelimiter
async def active_afk(_, message):
@use_chat_lang()
async def active_afk(_, message, strings):
if message.sender_chat:
return await kirimPesan(message, "This feature not supported for channel.")
return await kirimPesan(message, strings("no_channel"))
user_id = message.from_user.id
verifier, reasondb = await is_afk(user_id)
if verifier:
@ -51,39 +54,39 @@ async def active_afk(_, message):
send = (
await message.reply_animation(
data,
caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}",
caption=strings("on_afk_msg_no_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago),
)
if str(reasonafk) == "None"
else await message.reply_animation(
data,
caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}\n\nReason: `{reasonafk}`",
caption=strings("on_afk_msg_with_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago, reas=reasonafk),
)
)
elif afktype == "photo":
send = (
await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}",
caption=strings("on_afk_msg_no_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago),
)
if str(reasonafk) == "None"
else await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}\n\nReason: `{reasonafk}`",
caption=strings("on_afk_msg_with_r").format(usr=message.from_user.first_name, tm=seenago, reas=reasonafk),
)
)
elif afktype == "text":
send = await message.reply_text(
f"**{message.from_user.first_name}** is back online and was away for {seenago}",
caption=strings("on_afk_msg_no_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago),
disable_web_page_preview=True,
)
elif afktype == "text_reason":
send = await message.reply_text(
f"**{message.from_user.first_name}** is back online and was away for {seenago}\n\nReason: `{reasonafk}`",
caption=strings("on_afk_msg_with_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago, reas=reasonafk),
disable_web_page_preview=True,
)
except Exception:
send = await message.reply_text(
f"**{message.from_user.first_name}** is back online",
strings("is_online").format(usr=message.from_user.first_name),
disable_web_page_preview=True,
)
await put_cleanmode(message.chat.id, send.id)
@ -179,27 +182,242 @@ async def active_afk(_, message):
}
await add_afk(user_id, details)
send = await kirimPesan(message, f"{message.from_user.mention} [<code>{message.from_user.id}</code>] is now AFK!.")
send = await kirimPesan(message, strings("now_afk").format(usr=message.from_user.mention, id=message.from_user.id))
await put_cleanmode(message.chat.id, send.id)
@app.on_message(filters.command("afkdel", COMMAND_HANDLER) & filters.group)
@ratelimiter
@adminsOnly("can_change_info")
async def afk_state(_, message):
@use_chat_lang()
async def afk_state(_, message, strings):
if not message.from_user:
return
usage = "**Usage:**\n/afkdel [ENABLE|DISABLE] to enable or disable auto delete message."
if len(message.command) == 1:
return await kirimPesan(message, usage)
return await kirimPesan(message, strings("afkdel_help").format(cmd=message.command[0]))
chat_id = message.chat.id
state = message.text.split(None, 1)[1].strip()
state = state.lower()
if state == "enable":
await cleanmode_on(chat_id)
await kirimPesan(message, "Enabled auto delete AFK message in this chat.")
await kirimPesan(message, strings("afkdel_enable"))
elif state == "disable":
await cleanmode_off(chat_id)
await kirimPesan(message, "Disabled auto delete AFK message.")
await kirimPesan(message, strings("afkdel_disable"))
else:
await kirimPesan(message, usage)
await kirimPesan(message, strings("afkdel_help").format(cmd=message.command[0]))
# Detect user that AFK based on Yukki Repo
@app.on_message(
filters.group & ~filters.bot & ~filters.via_bot,
group=1,
)
@use_chat_lang()
async def chat_watcher_func(client, message, strings):
if message.sender_chat:
return
userid = message.from_user.id
user_name = message.from_user.mention
if message.entities:
possible = ["/afk", f"/afk@{client.me.username}", "!afk"]
message_text = message.text or message.caption
for entity in message.entities:
if entity.type == enums.MessageEntityType.BOT_COMMAND:
if (message_text[0 : 0 + entity.length]).lower() in possible:
return
msg = ""
replied_user_id = 0
# Self AFK
verifier, reasondb = await is_afk(userid)
if verifier:
await remove_afk(userid)
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago)
if afktype == "text_reason":
msg += strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk)
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago),
)
else:
send = await message.reply_animation(
data,
caption=strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk),
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{userid}.jpg",
caption=strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago),
)
else:
send = await message.reply_photo(
photo=f"downloads/{userid}.jpg",
caption=strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk),
)
except:
msg += strings("is_online").format(usr=user_name, id=userid)
# Replied to a User which is AFK
if message.reply_to_message:
try:
replied_first_name = message.reply_to_message.from_user.mention
replied_user_id = message.reply_to_message.from_user.id
verifier, reasondb = await is_afk(replied_user_id)
if verifier:
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago)
if afktype == "text_reason":
msg += strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk)
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago),
)
else:
send = await message.reply_animation(
data,
caption=strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk),
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{replied_user_id}.jpg",
caption=strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago),
)
else:
send = await message.reply_photo(
photo=f"downloads/{replied_user_id}.jpg",
caption=strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk),
)
except Exception:
msg += strings("is_afk").format(usr=replied_first_name, id=replied_user_id)
except:
pass
# If username or mentioned user is AFK
if message.entities:
entity = message.entities
j = 0
for x in range(len(entity)):
if (entity[j].type) == enums.MessageEntityType.MENTION:
found = re.findall("@([_0-9a-zA-Z]+)", message.text)
try:
get_user = found[j]
user = await app.get_users(get_user)
if user.id == replied_user_id:
j += 1
continue
except:
j += 1
continue
verifier, reasondb = await is_afk(user.id)
if verifier:
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago)
if afktype == "text_reason":
msg += strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk)
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago),
)
else:
send = await message.reply_animation(
data,
caption=strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk),
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{user.id}.jpg",
caption=strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago),
)
else:
send = await message.reply_photo(
photo=f"downloads/{user.id}.jpg",
caption=strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk),
)
except:
msg += strings("is_afk").format(usr=user.first_name[:25], id=user.id)
elif (entity[j].type) == enums.MessageEntityType.TEXT_MENTION:
try:
user_id = entity[j].user.id
if user_id == replied_user_id:
j += 1
continue
first_name = entity[j].user.first_name
except:
j += 1
continue
verifier, reasondb = await is_afk(user_id)
if verifier:
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago)
if afktype == "text_reason":
msg += strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk)
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago),
)
else:
send = await message.reply_animation(
data,
caption=strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk),
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
caption=strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago),
)
else:
send = await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
caption=strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk),
)
except:
msg += strings("is_afk").format(usr=first_name[:25], id=user_id)
j += 1
if msg != "":
try:
send = await message.reply_text(msg, disable_web_page_preview=True)
except:
pass
try:
await put_cleanmode(message.chat.id, send.id)
except:
pass

View file

@ -37,6 +37,7 @@ Supported Link:
Credit: <a href='https://github.com/sanjit-sinha/PyBypass'>PyBypass</a>
"""
# Stopped development for this plugin since always changed time by time.
async def pling_bypass(url):
try:

View file

@ -1,234 +0,0 @@
#
# Copyright (C) 2021-2022 by TeamYukki@Github, < https://github.com/TeamYukki >.
#
# This file is part of < https://github.com/TeamYukki/YukkiAFKBot > project,
# and is released under the "GNU v3.0 License Agreement".
# Please see < https://github.com/TeamYukki/YukkiAFKBot/blob/master/LICENSE >
#
# All rights reserved.
#
# Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import re
import time
from pyrogram import enums, filters
from database.afk_db import is_afk, remove_afk
from misskaty import BOT_USERNAME, app
from misskaty.helper.human_read import get_readable_time2
from utils import put_cleanmode
# Detect user that AFK based on Yukki Repo
@app.on_message(
filters.group & ~filters.bot & ~filters.via_bot,
group=1,
)
async def chat_watcher_func(_, message):
if message.sender_chat:
return
userid = message.from_user.id
user_name = message.from_user.first_name
if message.entities:
possible = ["/afk", f"/afk@{BOT_USERNAME}", "!afk"]
message_text = message.text or message.caption
for entity in message.entities:
if entity.type == enums.MessageEntityType.BOT_COMMAND:
if (message_text[0 : 0 + entity.length]).lower() in possible:
return
msg = ""
replied_user_id = 0
# Self AFK
verifier, reasondb = await is_afk(userid)
if verifier:
await remove_afk(userid)
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += f"**{user_name[:25]}** is back online and was away for {seenago}\n\n"
if afktype == "text_reason":
msg += f"**{user_name[:25]}** is back online and was away for {seenago}\n\n**Reason:** {reasonafk}\n\n"
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=f"**{user_name[:25]}** is back online and was away for {seenago}\n\n",
)
else:
send = await message.reply_animation(
data,
caption=f"**{user_name[:25]}** is back online and was away for {seenago}\n\n**Reason:** {reasonafk}\n\n",
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{userid}.jpg",
caption=f"**{user_name[:25]}** is back online and was away for {seenago}\n\n",
)
else:
send = await message.reply_photo(
photo=f"downloads/{userid}.jpg",
caption=f"**{user_name[:25]}** is back online and was away for {seenago}\n\n**Reason:** {reasonafk}\n\n",
)
except:
msg += f"**{user_name[:25]}** is back online.\n\n"
# Replied to a User which is AFK
if message.reply_to_message:
try:
replied_first_name = message.reply_to_message.from_user.first_name
replied_user_id = message.reply_to_message.from_user.id
verifier, reasondb = await is_afk(replied_user_id)
if verifier:
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += f"**{replied_first_name[:25]}** is AFK since {seenago} ago.\n\n"
if afktype == "text_reason":
msg += f"**{replied_first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n"
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=f"**{replied_first_name[:25]}** is AFK since {seenago} ago.\n\n",
)
else:
send = await message.reply_animation(
data,
caption=f"**{replied_first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n",
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{replied_user_id}.jpg",
caption=f"**{replied_first_name[:25]}** is AFK since {seenago} ago.\n\n",
)
else:
send = await message.reply_photo(
photo=f"downloads/{replied_user_id}.jpg",
caption=f"**{replied_first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n",
)
except Exception:
msg += f"**{replied_first_name}** is AFK\n\n"
except:
pass
# If username or mentioned user is AFK
if message.entities:
entity = message.entities
j = 0
for x in range(len(entity)):
if (entity[j].type) == enums.MessageEntityType.MENTION:
found = re.findall("@([_0-9a-zA-Z]+)", message.text)
try:
get_user = found[j]
user = await app.get_users(get_user)
if user.id == replied_user_id:
j += 1
continue
except:
j += 1
continue
verifier, reasondb = await is_afk(user.id)
if verifier:
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += f"**{user.first_name[:25]}** is AFK since {seenago} ago.\n\n"
if afktype == "text_reason":
msg += f"**{user.first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n"
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=f"**{user.first_name[:25]}** is AFK since {seenago} ago.\n\n",
)
else:
send = await message.reply_animation(
data,
caption=f"**{user.first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason**: {reasonafk}\n\n",
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{user.id}.jpg",
caption=f"**{user.first_name[:25]}** is AFK since {seenago} ago.\n\n",
)
else:
send = await message.reply_photo(
photo=f"downloads/{user.id}.jpg",
caption=f"**{user.first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n",
)
except:
msg += f"**{user.first_name[:25]}** is AFK\n\n"
elif (entity[j].type) == enums.MessageEntityType.TEXT_MENTION:
try:
user_id = entity[j].user.id
if user_id == replied_user_id:
j += 1
continue
first_name = entity[j].user.first_name
except:
j += 1
continue
verifier, reasondb = await is_afk(user_id)
if verifier:
try:
afktype = reasondb["type"]
timeafk = reasondb["time"]
data = reasondb["data"]
reasonafk = reasondb["reason"]
seenago = get_readable_time2((int(time.time() - timeafk)))
if afktype == "text":
msg += f"**{first_name[:25]}** is AFK since {seenago} ago.\n\n"
if afktype == "text_reason":
msg += f"**{first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n"
if afktype == "animation":
if str(reasonafk) == "None":
send = await message.reply_animation(
data,
caption=f"**{first_name[:25]}** is AFK since {seenago} ago.\n\n",
)
else:
send = await message.reply_animation(
data,
caption=f"**{first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n",
)
if afktype == "photo":
if str(reasonafk) == "None":
send = await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
caption=f"**{first_name[:25]}** is AFK since {seenago} ago.\n\n",
)
else:
send = await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
caption=f"**{first_name[:25]}** is AFK since {seenago} ago.\n\n**Reason:** {reasonafk}\n\n",
)
except:
msg += f"**{first_name[:25]}** is AFK\n\n"
j += 1
if msg != "":
try:
send = await message.reply_text(msg, disable_web_page_preview=True)
except:
return
try:
await put_cleanmode(message.chat.id, send.id)
except:
return

View file

@ -17,6 +17,7 @@ from pyrogram import enums, filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app, user, botStartTime, BOT_NAME
from misskaty.helper.localization import use_chat_lang
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
@ -40,7 +41,8 @@ async def edit_or_reply(msg, **kwargs):
@app.on_message(filters.command(["logs"], COMMAND_HANDLER) & filters.user(SUDO))
async def log_file(bot, message):
@use_chat_lang()
async def log_file(bot, message, strings):
"""Send log file"""
try:
await message.reply_document(
@ -50,7 +52,7 @@ async def log_file(bot, message):
[
[
InlineKeyboardButton(
"❌ Close",
strings("cl_btn"),
f"close#{message.from_user.id}",
)
]
@ -105,11 +107,12 @@ RAM Usage: `{virtual_memory().percent}%`
@app.on_message(filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_edited_message(filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO))
@user.on_message(filters.command(["shell", "sh"], ".") & filters.me)
async def shell(_, m):
@use_chat_lang()
async def shell(_, m, strings):
cmd = m.text.split(" ", 1)
if len(m.command) == 1:
return await edit_or_reply(m, text="No command to execute was given.")
msg = await editPesan(m, "<i>Processing exec pyrogram...</i>") if m.from_user.is_self else await kirimPesan(m, "<i>Processing exec pyrogram...</i>")
return await edit_or_reply(m, text=strings("no_cmd"))
msg = await editPesan(m, strings("run_exec")) if m.from_user.is_self else await kirimPesan(m, strings("run_exec"))
shell = (await shell_exec(cmd[1]))[0]
if len(shell) > 3000:
with open("shell_output.txt", "w") as file:
@ -118,7 +121,7 @@ async def shell(_, m):
await m.reply_document(
document=doc,
file_name=doc.name,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="❌ Close", callback_data=f"close#{m.from_user.id}")]]),
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
await msg.delete()
try:
@ -130,22 +133,23 @@ async def shell(_, m):
m,
text=shell,
parse_mode=enums.ParseMode.HTML,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="❌ Close", callback_data=f"close#{m.from_user.id}")]]),
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
if not m.from_user.is_self:
await msg.delete()
else:
await m.reply("No Reply")
await m.reply(strings("no_reply"))
@app.on_message((filters.command(["ev", "run"], COMMAND_HANDLER) | filters.regex(r"app.run\(\)$")) & filters.user(SUDO))
@app.on_edited_message((filters.command(["ev", "run"]) | filters.regex(r"app.run\(\)$")) & filters.user(SUDO))
@user.on_message(filters.command(["ev", "run"], ".") & filters.me)
async def evaluation_cmd_t(_, m):
@use_chat_lang()
async def evaluation_cmd_t(_, m, strings):
if (m.command and len(m.command) == 1) or m.text == "app.run()":
return await edit_or_reply(m, text="__No evaluate message!__")
return await edit_or_reply(m, text=strings("no_eval"))
cmd = m.text.split(" ", 1)[1] if m.command else m.text.split("\napp.run()")[0]
status_message = await editPesan(m, "<i>Processing eval pyrogram..</i>") if m.from_user.is_self else await kirimPesan(m, "<i>Processing eval pyrogram..</i>", quote=True)
status_message = await editPesan(m, strings("run_eval")) if m.from_user.is_self else await kirimPesan(m, strings("run_eval"), quote=True)
old_stderr = sys.stderr
old_stdout = sys.stdout
@ -201,7 +205,7 @@ async def evaluation_cmd_t(_, m):
elif stdout:
evaluation = stdout
else:
evaluation = "Success"
evaluation = strings("success")
final_output = f"**EVAL**:\n`{cmd}`\n\n**OUTPUT**:\n`{evaluation.strip()}`\n"
@ -213,7 +217,7 @@ async def evaluation_cmd_t(_, m):
caption=f"<code>{cmd[1][: 4096 // 4 - 1]}</code>",
disable_notification=True,
thumb="assets/thumb.jpg",
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="❌ Close", callback_data=f"close#{m.from_user.id}")]]),
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
os.remove("MissKatyEval.txt")
await status_message.delete()
@ -222,7 +226,7 @@ async def evaluation_cmd_t(_, m):
m,
text=final_output,
parse_mode=enums.ParseMode.MARKDOWN,
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="❌ Close", callback_data=f"close#{m.from_user.id}")]]),
reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
if not m.from_user.is_self:
await status_message.delete()
@ -230,15 +234,16 @@ async def evaluation_cmd_t(_, m):
# Update and restart bot
@app.on_message(filters.command(["update"], COMMAND_HANDLER) & filters.user(SUDO))
async def update_restart(_, message):
@use_chat_lang()
async def update_restart(_, message, strings):
try:
out = (await shell_exec("git pull"))[0]
if "Already up to date." in str(out):
return await message.reply_text("Its already up-to date!")
return await message.reply_text(strings("already_up"))
await message.reply_text(f"<code>{out}</code>")
except Exception as e:
return await message.reply_text(str(e))
msg = await message.reply_text("<b>Updated with default branch, restarting now.</b>")
msg = await message.reply_text(strings("up_and_rest"))
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

@ -159,7 +159,6 @@ async def memify(client, message):
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):

View file

@ -15,10 +15,11 @@ from pyrogram import enums, filters
from pyrogram.errors import FloodWait
from pyrogram.types import InlineKeyboardMarkup
from misskaty import BOT_USERNAME, app
from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import *
from misskaty.helper import gen_ik_buttons, get_duration, is_url, progress_for_pyrogram, screenshot_flink, take_ss
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
LOGGER = getLogger(__name__)
@ -32,40 +33,41 @@ __HELP__ = """"
@app.on_message(filters.command(["genss"], COMMAND_HANDLER))
@ratelimiter
async def genss(client, m):
@use_chat_lang()
async def genss(c, m, strings):
if not m.from_user:
return
replied = m.reply_to_message
if len(m.command) == 2 and is_url(m.command[1]):
snt = await kirimPesan(m, "Give me some time to process your request!! 😴", quote=True)
snt = await kirimPesan(m, strings("wait_msg"), quote=True)
duration = await get_duration(m.command[1])
if isinstance(duration, str):
return await editPesan(snt, "😟 Sorry! I cannot open the file.")
return await editPesan(snt, strings("fail_open"))
btns = gen_ik_buttons()
await editPesan(snt, f"Now choose how many result for screenshot? 🥳.\n\nTotal duration: `{datetime.timedelta(seconds=duration)}` (`{duration}s`)", reply_markup=InlineKeyboardMarkup(btns))
await editPesan(snt, strings("choose_no_ss").format(td=datetime.timedelta(seconds=duration), dur=duration), reply_markup=InlineKeyboardMarkup(btns))
elif replied and replied.media:
vid = [replied.video, replied.document]
media = next((v for v in vid if v is not None), None)
if media is None:
return await kirimPesan(m, "Reply to a Telegram Video or document as video to generate screenshoot!", quote=True)
process = await kirimPesan(m, "<code>Processing, please wait..</code>", quote=True)
return await kirimPesan(m, strings("no_reply"), quote=True)
process = await kirimPesan(m, strings("wait_dl"), quote=True)
if media.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("limit_dl"))
c_time = time.time()
dl = await replied.download(
file_name="/downloads/",
progress=progress_for_pyrogram,
progress_args=("Trying to download, please wait..", process, c_time),
progress_args=(strings("dl_progress"), process, c_time),
)
the_real_download_location = os.path.join("/downloads/", os.path.basename(dl))
if the_real_download_location is not None:
try:
await editPesan(process, f"File video berhasil didownload dengan path <code>{the_real_download_location}</code>.")
await editPesan(process, strings("success_dl_msg"))
await sleep(2)
images = await take_ss(the_real_download_location)
await editPesan(process, "Mencoba mengupload, hasil generate screenshot..")
await client.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO)
await editPesan(process, strings("up_progress"))
await c.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO)
try:
await gather(
@ -84,7 +86,7 @@ async def genss(client, m):
)
await kirimPesan(
m,
f"☑️ Uploaded [1] screenshoot.\n\n{m.from_user.first_name} (<code>{m.from_user.id}</code>)\n#️⃣ #ssgen #id{m.from_user.id}\n\nSS Generate by @{BOT_USERNAME}",
strings("up_msg").format(namma=m.from_user.mention, id=m.from_user.id, bot_uname=c.me.username),
reply_to_message_id=m.id,
)
await process.delete()
@ -94,14 +96,14 @@ async def genss(client, m):
except:
pass
except Exception as exc:
await kirimPesan(m, f"Gagal generate screenshot.\n\n{exc}")
await kirimPesan(m, strings("err_ssgen").format(exc=exc))
try:
os.remove(images)
os.remove(the_real_download_location)
except:
pass
else:
await kirimPesan(m, "Reply to a Telegram media to get screenshots from media..")
await kirimPesan(m, strings("no_reply"))
@app.on_callback_query(filters.regex(r"^scht"))

View file

@ -27,18 +27,16 @@ Give reputation to other people in group.
karma_positive_group = 3
karma_negative_group = 4
regex_upvote = r"^(\+|\+\+|\+1|thx|tnx|ty|thank you|thanx|thanks|pro|cool|good|makasih|👍|\+\+ .+)$"
regex_downvote = r"^(-|--|-1|👎|-- .+)$"
regex_upvote = r"^(\+|\+\+|\+1|thx|tnx|ty|tq|thank you|thanx|thanks|pro|cool|good|agree|makasih|👍|\+\+ .+)$"
regex_downvote = r"^(-|--|-1|not cool|disagree|worst|bad|👎|-- .+)$"
n = "\n"
w = " "
bold = lambda x: f"**{x}:** "
bold_ul = lambda x: f"**--{x}:**-- "
mono = lambda x: f"`{x}`{n}"
def section(
title: str,
body: dict,
@ -48,18 +46,32 @@ def section(
text = (bold_ul(title) + n) if underline else bold(title) + n
for key, value in body.items():
text += indent * w + bold(key) + ((value[0] + n) if isinstance(value, list) else mono(value))
text += (
indent * w
+ bold(key)
+ ((value[0] + n) if isinstance(value, list) else mono(value))
)
return text
async def get_user_id_and_usernames(client) -> dict:
with client.storage.lock, client.storage.conn:
users = client.storage.conn.execute('SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null').fetchall()
return {user[0]: user[3] for user in users}
users = client.storage.conn.execute(
'SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null'
).fetchall()
users_ = {}
for user in users:
users_[user[0]] = user[3]
return users_
@app.on_message(
filters.text & filters.group & filters.incoming & filters.reply & filters.regex(regex_upvote, re.IGNORECASE) & ~filters.via_bot & ~filters.bot,
filters.text
& filters.group
& filters.incoming
& filters.reply
& filters.regex(regex_upvote, re.IGNORECASE)
& ~filters.via_bot
& ~filters.bot,
group=karma_positive_group,
)
@capture_err
@ -79,15 +91,25 @@ async def upvote(_, message):
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma + 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
await message.reply_text(f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}")
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
await message.reply_text(
f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
)
@app.on_message(
filters.text & filters.group & filters.incoming & filters.reply & filters.regex(regex_downvote, re.IGNORECASE) & ~filters.via_bot & ~filters.bot,
filters.text
& filters.group
& filters.incoming
& filters.reply
& filters.regex(regex_downvote, re.IGNORECASE)
& ~filters.via_bot
& ~filters.bot,
group=karma_negative_group,
)
@capture_err
@ -102,22 +124,37 @@ async def downvote(_, message):
return
chat_id = message.chat.id
user_id = message.from_user.id
current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma - 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
user_id = message.reply_to_message.from_user.id
user_mention = message.reply_to_message.from_user.mention
current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma - 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
await message.reply_text(f"Decremented Karma Of {user_mention} By 1 \nTotal Points: {karma}")
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
await message.reply_text(
f"Decremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
)
@app.on_message(filters.command("karma") & filters.group)
@capture_err
@ratelimiter
async def command_karma(_, message):
chat_id = message.chat.id
if not message.reply_to_message:
@ -149,22 +186,25 @@ async def command_karma(_, message):
if int(user_idd) not in list(userdb.keys()):
continue
username = userdb[int(user_idd)]
karma[f"@{username}"] = [f"**{str(karma_count)}**"]
karma["@" + username] = ["**" + str(karma_count) + "**"]
limit += 1
await m.edit(section(msg, karma))
else:
if not message.reply_to_message.from_user:
return await message.reply("Anon user hash no karma.")
return await message.reply("Anon user has no karma.")
user_id = message.reply_to_message.from_user.id
karma = await get_karma(chat_id, await int_to_alpha(user_id))
karma = karma["karma"] if karma else 0
await message.reply_text(f"**Total Points**: __{karma}__")
if karma:
karma = karma["karma"]
await message.reply_text(f"**Total Points**: __{karma}__")
else:
karma = 0
await message.reply_text(f"**Total Points**: __{karma}__")
@app.on_message(filters.command("karma_toggle") & ~filters.private)
@adminsOnly
@ratelimiter
@adminsOnly("can_change_info")
async def captcha_state(_, message):
usage = "**Usage:**\n/karma_toggle [ENABLE|DISABLE]"
if len(message.command) != 2:
@ -174,9 +214,9 @@ async def captcha_state(_, message):
state = state.lower()
if state == "enable":
await karma_on(chat_id)
await message.reply_text("Enabled karma system.")
await message.reply_text("Enabled Karma System for this chat.")
elif state == "disable":
await karma_off(chat_id)
await message.reply_text("Disabled karma system.")
await message.reply_text("Disabled Karma System for this chat.")
else:
await message.reply_text(usage)
await message.reply_text(usage)

View file

@ -56,11 +56,11 @@ DETAILS
file_info.message_type
try:
link = await mediainfo_paste(out, "MissKaty Mediainfo")
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
try:
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text)
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
markup = None
with io.BytesIO(str.encode(body_text)) as out_file:
@ -91,11 +91,11 @@ DETAILS
# link = await post_to_telegraph(False, title, body_text)
try:
link = await mediainfo_paste(out, "MissKaty Mediainfo")
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
try:
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text)
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
markup = None
with io.BytesIO(str.encode(output)) as out_file:

View file

@ -7,10 +7,12 @@ from pyrogram import filters, __version__
from pyrogram.errors import ChannelInvalid, ChannelPrivate, ChatAdminRequired, ChatNotModified
from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import BOT_NAME, BOT_USERNAME, app, scheduler
from database.locale_db import get_db_lang
from misskaty import BOT_NAME, app, scheduler
from misskaty.core.message_utils import *
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.decorator.permissions import require_admin
from misskaty.helper.localization import use_chat_lang, langdict
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, TZ
__MODULE__ = "NightMode"
@ -85,46 +87,49 @@ def extract_time(time_val: str):
async def un_mute_chat(chat_id: int, perm: ChatPermissions):
getlang = await get_db_lang(chat_id)
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, langdict[getlang]["nightmodev2"]["nmd_off_not_admin"].format(chat_id=chat_id, bname=BOT_NAME))
except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_nightmode_{chat_id}")
await app.send_message(LOG_CHANNEL, 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, langdict[getlang]["nightmodev2"]["nmd_off_not_present"].format(chat_id=chat_id, bname=BOT_NAME))
except ChatNotModified:
pass
except Exception as e:
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`\n" f"ERROR: `{e}`")
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_err"].format(chat_id=chat_id, e=e))
else:
job = scheduler.get_job(f"enable_nightmode_{chat_id}")
close_at = job.next_run_time
await app.send_message(chat_id, 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, langdict[getlang]["nightmodev2"]["nmd_off_success"].format(dt=tglsekarang(), close_at=close_at), reply_markup=reply_markup)
async def mute_chat(chat_id: int):
getlang = await get_db_lang(chat_id)
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, langdict[getlang]["nightmodev2"]["nmd_on_not_admin"].format(chat_id=chat_id, bname=BOT_NAME))
except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_nightmode_{chat_id}")
await app.send_message(LOG_CHANNEL, 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, langdict[getlang]["nightmodev2"]["nmd_on_not_present"].format(chat_id=chat_id, bname=BOT_NAME))
except ChatNotModified:
pass
except Exception as e:
await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`\n" f"ERROR: `{e}`")
await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_err"].format(chat_id=chat_id, e=e))
else:
job = scheduler.get_job(f"disable_nightmode_{chat_id}")
open_at = job.next_run_time
await app.send_message(chat_id, 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, langdict[getlang]["nightmodev2"]["nmd_on_success"].format(dt=tglsekarang(), open_at=open_at), reply_markup=reply_markup)
@app.on_message(filters.command("nightmode", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_change_info")
async def nightmode_handler(c, msg):
@require_admin(permissions=["can_change_info"])
@use_chat_lang()
async def nightmode_handler(c, msg, strings):
chat_id = msg.chat.id
if "-d" in msg.text:
@ -134,8 +139,8 @@ 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 isn't enabled in this chat.")
return await kirimPesan(msg, strings("nmd_disabled"))
return await kirimPesan(msg, strings("nmd_not_enabled"))
starttime = re.findall(r"-s=(\d+:\d+)", msg.text)
start = starttime[0] if starttime else "00:00"
@ -144,13 +149,13 @@ async def nightmode_handler(c, msg):
try:
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.")
return await kirimPesan(msg, strings("invalid_time_format"))
lockdur = re.findall(r"-e=(\w+)", msg.text)
lockdur = lockdur[0] if lockdur else "6h"
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, strings("invalid_lockdur"))
if start_timestamp < now:
start_timestamp = start_timestamp + timedelta(days=1)
@ -162,13 +167,14 @@ async def nightmode_handler(c, msg):
# 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)
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, strings("schedule_already_on"))
await kirimPesan(msg, strings("nmd_enable_success").format(st=start_timestamp.strftime("%H:%M:%S"), lockdur=lockdur))
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)
@use_chat_lang()
async def callbackanightmd(c, q, strings):
await q.answer(strings("nmd_cb").format(bname=c.me.first_name, ver=__version__), show_alert=True)

View file

@ -20,7 +20,7 @@ from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "OCR"
__HELP__ = "/ocr [reply to photo] - Read Text From Image"
__HELP__ = f"/ocr [reply to photo] - Read Text From Image"
@app.on_message(filters.command(["ocr"], COMMAND_HANDLER))

View file

@ -0,0 +1,292 @@
"""
* @author yasir <yasiramunandar@gmail.com>
* @date 2022-12-01 09:12:27
* @lastModified 2023-03-30 09:33:16
* @projectName MissKatyPyro
* Copyright @YasirPedia All rights reserved
"""
import re
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.users_chats_db import db
from pyrogram import filters
from misskaty import app, BOT_USERNAME, HELPABLE, BOT_NAME
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
from misskaty.core.message_utils import *
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper import bot_sys_stats, paginate_modules
from misskaty.helper.localization import use_chat_lang
home_keyboard_pm = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(text="Commands ❓", callback_data="bot_commands"),
InlineKeyboardButton(
text="Source Code 🛠",
url="https://github.com/yasirarism/MissKatyPyro",
),
],
[
InlineKeyboardButton(
text="System Stats 🖥",
callback_data="stats_callback",
),
InlineKeyboardButton(text="Dev 👨", url="https://t.me/YasirArisM"),
],
[
InlineKeyboardButton(
text="Add Me To Your Group 🎉",
url=f"http://t.me/{BOT_USERNAME}?startgroup=new",
)
],
]
)
home_text_pm = f"Hey there! My name is {BOT_NAME}. I have many useful features for you, feel free to add me to your group.\n\nIf you want give coffee to my owner you can send /donate command for more info."
keyboard = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(text="Help ❓", url=f"t.me/{BOT_USERNAME}?start=help"),
InlineKeyboardButton(
text="Source Code <20>",
url="https://github.com/yasirarism/MissKatyPyro",
),
],
[
InlineKeyboardButton(
text="System Stats 💻",
callback_data="stats_callback",
),
InlineKeyboardButton(text="Dev 👨", url="https://t.me/YasirArisM"),
],
]
)
@app.on_message(filters.command("start", COMMAND_HANDLER))
@use_chat_lang()
async def start(_, message, strings):
if message.chat.type.value != "private":
if not await db.get_chat(message.chat.id):
total = await app.get_chat_members_count(message.chat.id)
await app.send_message(
LOG_CHANNEL,
strings("newgroup_log").format(jdl=message.chat.title, id=message.chat.id, c=total),
)
await db.add_chat(message.chat.id, message.chat.title)
nama = (
message.from_user.mention
if message.from_user
else message.sender_chat.title
)
return await message.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=strings("start_msg").format(kamuh=nama),
reply_markup=keyboard,
)
if not await db.is_user_exist(message.from_user.id):
await db.add_user(message.from_user.id, message.from_user.first_name)
await app.send_message(
LOG_CHANNEL,
strings("newuser_log").format(id=message.from_user.id, nm=message.from_user.mention),
)
if len(message.text.split()) > 1:
name = (message.text.split(None, 1)[1]).lower()
if "_" in name:
module = name.split("_", 1)[1]
text = (
strings("help_name").format(mod=HELPABLE[module].__MODULE__)
+ HELPABLE[module].__HELP__
)
await kirimPesan(message, text, disable_web_page_preview=True)
elif name == "help":
text, keyb = await help_parser(message.from_user.first_name)
await kirimPesan(
message,
text,
reply_markup=keyb,
)
else:
await message.reply_photo(
photo="https://telegra.ph/file/90e9a448bc2f8b055b762.jpg",
caption=home_text_pm,
reply_markup=home_keyboard_pm,
)
@app.on_callback_query(filters.regex("bot_commands"))
@ratelimiter
async def commands_callbacc(_, CallbackQuery):
text, keyboard = await help_parser(CallbackQuery.from_user.mention)
await app.send_message(
CallbackQuery.message.chat.id,
text=text,
reply_markup=keyboard,
)
await hapusPesan(CallbackQuery.message)
@app.on_callback_query(filters.regex("stats_callback"))
@ratelimiter
async def stats_callbacc(_, CallbackQuery):
text = await bot_sys_stats()
await app.answer_callback_query(CallbackQuery.id, text, show_alert=True)
@app.on_message(filters.command("help", COMMAND_HANDLER))
@ratelimiter
@use_chat_lang()
async def help_command(_, message, strings):
if not message.from_user: return
if message.chat.type.value != "private":
if not await db.get_chat(message.chat.id):
total = await app.get_chat_members_count(message.chat.id)
await app.send_message(
LOG_CHANNEL,
strings("newgroup_log").format(jdl=message.chat.title, id=message.chat.id, c=total),
)
await db.add_chat(message.chat.id, message.chat.title)
if len(message.command) >= 2:
name = (message.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE:
key = InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
text=strings("click_me"),
url=f"t.me/{BOT_USERNAME}?start=help_{name}",
)
],
]
)
await kirimPesan(
message,
strings("click_btn"),
reply_markup=key,
)
else:
await kirimPesan(message, strings("pm_detail"), reply_markup=keyboard)
else:
await kirimPesan(message, strings("pm_detail"), reply_markup=keyboard)
else:
if not await db.is_user_exist(message.from_user.id):
await db.add_user(message.from_user.id, message.from_user.first_name)
await app.send_message(
LOG_CHANNEL,
strings("newuser_log").format(id=message.from_user.id, nm=message.from_user.mention),
)
if len(message.command) >= 2:
name = (message.text.split(None, 1)[1]).replace(" ", "_").lower()
if str(name) in HELPABLE:
text = (
strings("help_name").format(mod=HELPABLE[name].__MODULE__)
+ HELPABLE[name].__HELP__
)
await kirimPesan(message, text, disable_web_page_preview=True)
else:
text, help_keyboard = await help_parser(message.from_user.first_name)
await kirimPesan(
message,
text,
reply_markup=help_keyboard,
disable_web_page_preview=True,
)
else:
text, help_keyboard = await help_parser(message.from_user.first_name)
await kirimPesan(
message, text, reply_markup=help_keyboard, disable_web_page_preview=True
)
async def help_parser(name, keyboard=None):
if not keyboard:
keyboard = InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help"))
return (
"""Hello {first_name}, My name is {bot_name}.
I'm a bot with some useful features. You can change language bot using /setlang command, but it's still 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.
""".format(
first_name=name,
bot_name="MissKaty",
),
keyboard,
)
@app.on_callback_query(filters.regex(r"help_(.*?)"))
@ratelimiter
@use_chat_lang()
async def help_button(client, query, strings):
home_match = re.match(r"help_home\((.+?)\)", query.data)
mod_match = re.match(r"help_module\((.+?)\)", query.data)
prev_match = re.match(r"help_prev\((.+?)\)", query.data)
next_match = re.match(r"help_next\((.+?)\)", query.data)
back_match = re.match(r"help_back", query.data)
create_match = re.match(r"help_create", query.data)
top_text = strings("help_txt").format(kamuh=query.from_user.first_name, bot=client.me.first_name)
if mod_match:
module = mod_match[1].replace(" ", "_")
text = strings("help_name").format(mod=HELPABLE[module].__MODULE__) + HELPABLE[module].__HELP__
await editPesan(
query.message,
text=text,
reply_markup=InlineKeyboardMarkup(
[[InlineKeyboardButton(strings("back_btn"), callback_data="help_back")]]
),
disable_web_page_preview=True,
)
elif home_match:
await app.send_message(
query.from_user.id,
text=home_text_pm,
reply_markup=home_keyboard_pm,
)
await hapusPesan(query.message)
elif prev_match:
curr_page = int(prev_match[1])
await editPesan(
query.message,
text=top_text,
reply_markup=InlineKeyboardMarkup(
paginate_modules(curr_page - 1, HELPABLE, "help")
),
disable_web_page_preview=True,
)
elif next_match:
next_page = int(next_match[1])
await editPesan(
query.message,
text=top_text,
reply_markup=InlineKeyboardMarkup(
paginate_modules(next_page + 1, HELPABLE, "help")
),
disable_web_page_preview=True,
)
elif back_match:
await editPesan(
query.message,
text=top_text,
reply_markup=InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help")),
disable_web_page_preview=True,
)
elif create_match:
text, keyboard = await help_parser(query)
await editPesan(
query.message,
text=text,
reply_markup=keyboard,
disable_web_page_preview=True,
)
return await client.answer_callback_query(query.id)

File diff suppressed because it is too large Load diff

View file

@ -11,6 +11,7 @@ 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, LOG_CHANNEL
LOGGER = getLogger(__name__)
@ -25,23 +26,21 @@ def rand_key():
@app.on_message(filters.command(["ytsearch"], COMMAND_HANDLER) & ~filters.channel)
@capture_err
@ratelimiter
async def ytsearch(_, message):
@use_chat_lang()
async def ytsearch(_, message, strings):
if message.sender_chat:
return await kirimPesan(message, "This feature not supported for channel.")
return await kirimPesan(message, strings("no_channel"))
if len(message.command) == 1:
return await kirimPesan(message, "Please input a query..!")
return await kirimPesan(message, strings("no_query"))
query = message.text.split(" ", maxsplit=1)[1]
search_key = rand_key()
YT_DB[search_key] = query
search = await main.VideosSearch(query).next()
if search["result"] == []:
return await message.reply(f"No result found for `{query}`")
return await message.reply(strings("no_res").format(kweri=query))
i = search["result"][0]
out = f"<b><a href={i['link']}>{i['title']}</a></b>"
out += f"\nPublished {i['publishedTime']}\n"
out += f"\n<b> Duration:</b> {i['duration']}"
out += f"\n<b> Views:</b> {i['viewCount']['short']}"
out += f"\n<b> Uploader:</b> <a href={i['channel']['link']}>{i['channel']['name']}</a>\n\n"
out = f"<b><a href={i['link']}>{i['title']}</a></b>\n"
out = strings("yts_msg").format(pub=i['publishedTime'], dur=i['duration'], vi=i['viewCount']['short'], clink=i['channel']['link'], cname=i['channel']['name'])
btn = InlineKeyboardMarkup(
[
[
@ -50,7 +49,7 @@ async def ytsearch(_, message):
callback_data=f"ytdl_scroll|{search_key}|1",
)
],
[InlineKeyboardButton("Download", callback_data=f"yt_gen|{i['id']}")],
[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")],
]
)
img = await get_ytthumb(i["id"])
@ -62,17 +61,18 @@ async def ytsearch(_, message):
@app.on_message(filters.command(["ytdown"], COMMAND_HANDLER))
@capture_err
@ratelimiter
async def ytdownv2(_, message):
@use_chat_lang()
async def ytdownv2(_, message, strings):
if not message.from_user:
return
return await kirimPesan(message, strings("no_channel"))
if len(message.command) == 1:
return await message.reply("Please input a valid YT-DLP Supported URL")
return await message.reply(strings("invalid_link"))
url = message.text.split(" ", maxsplit=1)[1]
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
try:
x = await ytdl.parse(url)
if x is None:
return await message.reply("Failed parse URL, check logs..")
return await message.reply(strings("err_parse"))
img = await get_ytthumb(x.key)
caption = x.caption
markup = x.buttons
@ -83,9 +83,10 @@ async def ytdownv2(_, message):
@app.on_callback_query(filters.regex(r"^yt_listall"))
@ratelimiter
async def ytdl_listall_callback(_, cq: CallbackQuery):
@use_chat_lang()
async def ytdl_listall_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
media, buttons = await ytdl.listview(callback[1])
@ -94,10 +95,11 @@ async def ytdl_listall_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^yt_extract_info"))
@ratelimiter
async def ytdl_extractinfo_callback(_, cq: CallbackQuery):
@use_chat_lang()
async def ytdl_extractinfo_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
await cq.answer("Please Wait...")
return await cq.answer(strings("unauth"), True)
await cq.answer(strings("wait"))
callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
if data := await ytdl.extract_info_from_key(callback[1]):
@ -120,9 +122,10 @@ async def ytdl_extractinfo_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^yt_(gen|dl)"))
@ratelimiter
async def ytdl_gendl_callback(_, cq: CallbackQuery):
@use_chat_lang()
async def ytdl_gendl_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|")
key = callback[1]
if callback[0] == "yt_gen":
@ -170,9 +173,10 @@ async def ytdl_gendl_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^ytdl_scroll"))
@ratelimiter
async def ytdl_scroll_callback(_, cq: CallbackQuery):
@use_chat_lang()
async def ytdl_scroll_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
return await cq.answer("Not your task", True)
return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|")
search_key = callback[1]
page = int(callback[2])
@ -180,13 +184,10 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery):
search = await main.VideosSearch(query).next()
i = search["result"][page]
out = f"<b><a href={i['link']}>{i['title']}</a></b>"
out += f"\nPublished {i['publishedTime']}\n"
out += f"\n<b> Duration:</b> {i['duration']}"
out += f"\n<b> Views:</b> {i['viewCount']['short']}"
out += f"\n<b> Uploader:</b> <a href={i['channel']['link']}>{i['channel']['name']}</a>\n\n"
out = strings("yts_msg").format(pub=i['publishedTime'], dur=i['duration'], vi=i['viewCount']['short'], clink=i['channel']['link'], cname=i['channel']['name'])
scroll_btn = [
[
InlineKeyboardButton("Back", callback_data=f"ytdl_scroll|{search_key}|{page-1}"),
InlineKeyboardButton(strings("back"), callback_data=f"ytdl_scroll|{search_key}|{page-1}"),
InlineKeyboardButton(
f"{page+1}/{len(search['result'])}",
callback_data=f"ytdl_scroll|{search_key}|{page+1}",
@ -195,11 +196,11 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery):
]
if page == 0:
if len(search["result"]) == 1:
return await cq.answer("That's the end of list", show_alert=True)
return await cq.answer(strings("endlist"), show_alert=True)
scroll_btn = [[scroll_btn.pop().pop()]]
elif page == (len(search["result"]) - 1):
scroll_btn = [[scroll_btn.pop().pop(0)]]
btn = [[InlineKeyboardButton("Download", callback_data=f"yt_gen|{i['id']}")]]
btn = [[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")]]
btn = InlineKeyboardMarkup(scroll_btn + btn)
await cq.edit_message_media(InputMediaPhoto(await get_ytthumb(i["id"]), caption=out), reply_markup=btn)