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: async def is_karma_on(chat_id: int) -> bool:
chat = await karmadb.find_one({"chat_id_toggle": chat_id}) 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): 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) 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}) ul = await localesdb.find_one({"chat_id": chat_id})
return ul["lang"] if ul else {} 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_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}", "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.", "purge_no_reply": "Reply to a message to purge from.",
"delete_no_reply": "Reply To A Message To Delete It", "delete_no_reply": "Reply To A Message To Delete It",
"pin_no_reply": "Reply to a message to pin/unpin 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}", "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>.", "private_not_allowed": "Perintah ini tidak dapat digunakan dalam obrolan pribadi, Jika anda membutuhkan bantuan, mohon gunakan perintah /help.",
"purge_no_reply": "Balas pesan untuk dihapus.", "purge_no_reply": "Balas ke pesan yang ingin dihapus.",
"delete_no_reply": "Balas Pesan Untuk Menghapusnya", "delete_no_reply": "Balas Pesan Untuk Menghapusnya",
"pin_no_reply": "Balas pesan untuk menyematkan/melepas pin.", "pin_no_reply": "Balas pesan untuk menyematkan/melepas pin.",
"report_no_reply": "Balas Pesan Untuk Melaporkan Pengguna Itu.", "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.", "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.", "ban_self_err": "Saya tidak dapat melarang diri saya sendiri, saya dapat pergi jika Anda mau.",
"report_self_err": "Mengapa Anda melaporkan diri sendiri?", "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.", "warn_self_err": "Saya tidak dapat memperingatkan diri sendiri.",
"mute_self_err": "Saya sendiri tidak dapat membisukan.", "mute_self_err": "Saya tidak dapat membisukan diri sendiri.",
"kick_sudo_err": "Wow, Anda ingin menendang pemilik saya?", "kick_sudo_err": "Wow, Anda ingin menendang pemilik saya yang spesial?",
"ban_sudo_err": "Wow, Anda ingin mencoba mencekal pemilik saya?", "ban_sudo_err": "Wow, Anda ingin mencoba membanned pemilik saya?",
"demote_sudo_err": "Wow, Anda ingin mencoba menurunkan pemilik saya?", "demote_sudo_err": "Wow, Anda ingin mencoba mendemote pemilik saya?",
"warn_sudo_err": "Wow, Anda ingin mencoba memberi peringatan kepada pemilik saya?", "warn_sudo_err": "Wow, Anda ingin mencoba memberi peringatan kepada pemilik saya?",
"mute_sudo_err": "Wow, Anda ingin mencoba membisukan pemilik saya?", "mute_sudo_err": "Wow, Anda ingin mencoba membisukan pemilik saya?",
"kick_admin_err": "Hah, sungguh gila jika saya bisa menendang seorang admin.", "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}", "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", "ban_msg": "**Pengguna yang Dilarang:** {mention} [{id}]\n**Dilarang Oleh:** {banner}\n",
"unban_msg": "__Banned dihapus oleh {mention}__", "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", "no_more_99": "Anda tidak dapat menggunakan lebih dari 99",
"banned_time": "**Dilarang Untuk:** {val}\n", "banned_time": "**Dilarang Untuk:** {val}\n",
"muted_time": "**Dimatikan Untuk:** {val}\n", "muted_time": "**Dimute Untuk:** {val}\n",
"banned_reason": "**Alasan:** {reas}", "banned_reason": "**Alasan:** {reas}",
"unban_channel_err": "Anda tidak dapat membatalkan pemblokiran saluran", "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}!", "unban_success": "Berhasil membatalkan pemblokiran {umention}!",
"give_idban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan pelarangan daftar", "give_idban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan pelarangan daftar",
"give_idunban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan untuk membatalkan larangan", "give_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!", "report_msg": "Melaporkan {user_mention} ke admin!",
"reported_is_admin": "Apakah Anda tahu bahwa pengguna yang Anda balas adalah seorang admin?", "reported_is_admin": "Apakah Anda tahu bahwa pengguna yang Anda balas adalah seorang admin?",
"user_no_warn": "Pengguna {mention} tidak memiliki peringatan.", "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", "warn_msg": "**Pengguna yang Diperingatkan:** {mention}\n**Diperingatkan Oleh:** {warner}\n**Alasan:** {reas}\n**Peringatan:** {twarn}/ 3",
"rmwarn_msg": "Peringatan {mention} telah dihapus.", "rmwarn_msg": "Peringatan {mention} telah dihapus.",
"unwarn_msg": "Peringatan dihapus oleh {mention}.", "unwarn_msg": "Peringatan dihapus oleh {mention}.",
@ -63,6 +63,6 @@
"unmute_msg": "Disuarakan! {umention}", "unmute_msg": "Disuarakan! {umention}",
"reply_to_rm_warn": "Balas pesan untuk menghapus peringatan pengguna.", "reply_to_rm_warn": "Balas pesan untuk menghapus peringatan pengguna.",
"exceed_warn_msg": "Jumlah peringatan dari {mention} terlampaui, DILARANG!", "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 🚨" "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.", "no_question": "Harap gunakan perintah <code>/{cmd} [question]</code> untuk mengajukan pertanyaan Anda menggunakan OpenAI.",
"find_answers_str": "Tunggu sebentar untuk mencari jawaban Anda..", "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}" "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_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_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...`", "wait_msg": "`Mohon tunggu sementara...`",
"err_link": "Sepertinya tautan yang Anda kirim tidak valid, pastikan tautan langsung dan bisa di unduh.", "err_link": "Sepertinya tautan yang Anda kirim tidak valid, pastikan tautan langsung dan bisa di unduh.",
"media_invalid": "Silakan balas ke media yang valid.", "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..", "dl_args_text": "Mencoba mengunduh..",
"mediainfo_help": "Gunakan perintah /{cmd} [tautan], atau balas telegram media dengan /{cmd}.", "mediainfo_help": "Gunakan perintah /{cmd} [tautan], atau balas telegram media dengan /{cmd}.",
"capt_media": " Hasil mediainfo anda..\n\n**Request Oleh:** {ment}", "capt_media": " Hasil mediainfo anda..\n\n**Diminta Oleh:** {ment}",
"viewweb": "💬 Buka di Web" "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..", "please_start_msg": "Tampaknya Anda belum pernah berinteraksi dengan saya dalam obrolan pribadi, Anda harus melakukannya dulu..",
"click_me": "Klik Saya", "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.", "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}" "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_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}", "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 <code>/help</code>.", "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.", "purge_no_reply": "Bales pesen sing arep dibusak.",
"delete_no_reply": "Bales Pesen Kanggo Mbusak", "delete_no_reply": "Bales Pesen Kanggo Mbusak",
"pin_no_reply": "Bales pesen sing arep disematke/copot.", "pin_no_reply": "Bales pesen sing arep disematke/copot.",
"report_no_reply": "Bales Pesen Kanggo Nglaporake Panganggo.", "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..", "purge_success": "Kasil mbusak {del_total} pesen..",
"user_not_found": "Aku ora bisa nemokake panganggo kuwi.", "user_not_found": "Aku ora bisa nemokake panganggo kuwi.",
"invalid_id_uname": "⚠️ panganggo/jeneng panganggo ora sah", "invalid_id_uname": "⚠️ panganggo/jeneng panganggo ora sah",
"kick_self_err": "Aku ora bisa nyepak awakku dhewe, aku bisa lunga yen sampeyan pengin.", "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.", "ban_self_err": "Aku ora bisa nglarang aku, aku bisa lunga yen sampeyan pengin.",
"report_self_err": "Kenging menapa panjenengan lapor piyambak?", "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.", "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?", "kick_sudo_err": "Wah, kowe arep nyepak juraganku?",
"ban_sudo_err": "Wah, sampeyan pengin nyoba nglarang pemilikku?", "ban_sudo_err": "Wah, sampeyan pengin nyoba nglarang pemilikku?",
"demote_sudo_err": "Wah, sampeyan pengin nyoba nurunake pemilikku?", "demote_sudo_err": "Wah, sampeyan pengin nyoba nurunake pemilikku?",
@ -51,7 +51,7 @@
"normal_promote": "Dipromosikan {umention}!", "normal_promote": "Dipromosikan {umention}!",
"pin_success": "**Semat [iki]({link}) pesen.**", "pin_success": "**Semat [iki]({link}) pesen.**",
"unpin_success": "**Pesen [iki] ({pranala}) ora disemat.**", "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!", "report_msg": "Kacarita {user_mention} menyang admin!",
"reported_is_admin": "Apa sampeyan ngerti yen pangguna sing sampeyan bales iku admin?", "reported_is_admin": "Apa sampeyan ngerti yen pangguna sing sampeyan bales iku admin?",
"user_no_warn": "Panganggo {mention} ora ana bebaya.", "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.", "no_question": "Tulung gunakake printah <code>/{cmd} [pitakon]</code> kanggo takon nganggo fitur OpenAI.",
"find_answers_str": "Ngenteni sedhela goleki jawabanmu..", "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}" "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...`", "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.", "err_link": "Kayak'e pranala sing dikirim ora valid, priksa link langsung lan bisa diundhuh.",
"media_invalid": "Mangga mbales media sing bener.", "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..", "dl_args_text": "Nyoba ngundhuh..",
"mediainfo_help": "Gunakake printah /{cmd} [link], utawa bales media telegram nganggo /{cmd}.", "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" "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..", "please_start_msg": "Koyone sampeyan ora tau sesambungan karo aku ing obrolan pribadi, sampeyan kudu nglakoni dhisik..",
"click_me": "Klik Aku", "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.", "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}" "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 asyncio
import importlib import importlib
import re
import os import os
import pickle import pickle
import traceback import traceback
from logging import getLogger from logging import getLogger
from pyrogram import __version__, filters, idle from pyrogram import __version__, idle
from pyrogram.raw.all import layer from pyrogram.raw.all import layer
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from database.users_chats_db import db
from misskaty import ( from misskaty import (
BOT_NAME, BOT_NAME,
BOT_USERNAME, BOT_USERNAME,
@ -26,12 +23,9 @@ from misskaty import (
app, app,
scheduler 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.plugins import ALL_MODULES
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO from misskaty.vars import SUDO
from utils import auto_clean, temp from utils import auto_clean
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
loop = asyncio.get_event_loop() loop = asyncio.get_event_loop()
@ -80,293 +74,6 @@ async def start_bot():
asyncio.create_task(auto_clean()) asyncio.create_task(auto_clean())
await idle() 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__": if __name__ == "__main__":
try: try:
loop.run_until_complete(start_bot()) 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") perms.append("can_manage_video_chats")
return perms 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( async def check_perms(
message: Union[CallbackQuery, Message], message: Union[CallbackQuery, Message],
@ -148,7 +189,6 @@ def adminsOnly(permission):
return subFunc return subFunc
def require_admin( def require_admin(
permissions: Union[list, str] = None, permissions: Union[list, str] = None,
allow_in_private: bool = False, allow_in_private: bool = False,

View file

@ -79,7 +79,7 @@ async def get_lang(message) -> str:
else: else:
raise TypeError(f"Update type '{message.__name__}' is not supported.") 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: if chat.type == ChatType.PRIVATE:
lang = lang or message.from_user.language_code or default_language 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")) return await message.reply_text(strings("no_promote_perm"))
if message.command[0][0] == "f": if message.command[0][0] == "f":
await message.chat.promote_member( await message.chat.promote_member(
user_id, user_id=user_id,
ChatPrivileges( can_change_info=bot.privileges.can_change_info,
can_change_info=bot.can_change_info, can_invite_users=bot.privileges.can_invite_users,
can_invite_users=bot.can_invite_users, can_delete_messages=bot.privileges.can_delete_messages,
can_delete_messages=bot.can_delete_messages, can_restrict_members=bot.privileges.can_restrict_members,
can_restrict_members=bot.can_restrict_members, can_pin_messages=bot.privileges.can_pin_messages,
can_pin_messages=bot.can_pin_messages, can_promote_members=bot.privileges.can_promote_members,
can_promote_members=bot.can_promote_members, can_manage_chat=bot.privileges.can_manage_chat,
can_manage_chat=bot.can_manage_chat, can_manage_video_chats=bot.privileges.can_manage_video_chats,
can_manage_voice_chats=bot.can_manage_voice_chats,
),
) )
return await message.reply_text(strings("full_promote").format(umention=umention)) return await message.reply_text(strings("full_promote").format(umention=umention))
await message.chat.promote_member( await message.chat.promote_member(
user_id, user_id=user_id,
ChatPrivileges( can_change_info=False,
can_change_info=False, can_invite_users=bot.privileges.can_invite_users,
can_invite_users=bot.can_invite_users, can_delete_messages=bot.privileges.can_delete_messages,
can_delete_messages=bot.can_delete_messages, can_restrict_members=bot.privileges.can_restrict_members,
can_restrict_members=False, can_pin_messages=bot.privileges.can_pin_messages,
can_pin_messages=False, can_promote_members=False,
can_promote_members=False, can_manage_chat=bot.privileges.can_manage_chat,
can_manage_chat=bot.can_manage_chat, can_manage_video_chats=bot.privileges.can_manage_video_chats,
can_manage_voice_chats=bot.can_manage_voice_chats,
),
) )
await message.reply_text(strings("normal_promote").format(umention=umention)) 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")) return await message.reply_text(strings("demote_self_err"))
if user_id in SUDO: if user_id in SUDO:
return await message.reply_text(strings("demote_sudo_err")) 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 umention = (await app.get_users(user_id)).mention
await message.reply_text(f"Demoted! {umention}") await message.reply_text(f"Demoted! {umention}")
@ -507,8 +513,8 @@ async def unmute(_, message, strings):
if not user_id: if not user_id:
return await message.reply_text(strings("user_not_found")) return await message.reply_text(strings("user_not_found"))
await message.chat.unban_member(user_id) await message.chat.unban_member(user_id)
(await app.get_users(user_id)).mention umention = (await app.get_users(user_id)).mention
await message.reply_text(strings("unmute_msg")) await message.reply_text(strings("unmute_msg").format(umention=umention))
@app.on_message(filters.command(["warn", "dwarn"], COMMAND_HANDLER) & filters.group) @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 # Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import time 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 database.afk_db import add_afk, cleanmode_off, cleanmode_on, is_afk, remove_afk
from misskaty import app 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.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import kirimPesan from misskaty.core.message_utils import kirimPesan
from misskaty.helper import get_readable_time2 from misskaty.helper import get_readable_time2
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER from misskaty.vars import COMMAND_HANDLER
from utils import put_cleanmode from utils import put_cleanmode
@ -34,9 +36,10 @@ Just type something in group to remove AFK Status."""
@capture_err @capture_err
@app.on_message(filters.command(["afk"], COMMAND_HANDLER)) @app.on_message(filters.command(["afk"], COMMAND_HANDLER))
@ratelimiter @ratelimiter
async def active_afk(_, message): @use_chat_lang()
async def active_afk(_, message, strings):
if message.sender_chat: 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 user_id = message.from_user.id
verifier, reasondb = await is_afk(user_id) verifier, reasondb = await is_afk(user_id)
if verifier: if verifier:
@ -51,39 +54,39 @@ async def active_afk(_, message):
send = ( send = (
await message.reply_animation( await message.reply_animation(
data, 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" if str(reasonafk) == "None"
else await message.reply_animation( else await message.reply_animation(
data, 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": elif afktype == "photo":
send = ( send = (
await message.reply_photo( await message.reply_photo(
photo=f"downloads/{user_id}.jpg", 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" if str(reasonafk) == "None"
else await message.reply_photo( else await message.reply_photo(
photo=f"downloads/{user_id}.jpg", 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": elif afktype == "text":
send = await message.reply_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, disable_web_page_preview=True,
) )
elif afktype == "text_reason": elif afktype == "text_reason":
send = await message.reply_text( 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, disable_web_page_preview=True,
) )
except Exception: except Exception:
send = await message.reply_text( 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, disable_web_page_preview=True,
) )
await put_cleanmode(message.chat.id, send.id) await put_cleanmode(message.chat.id, send.id)
@ -179,27 +182,242 @@ async def active_afk(_, message):
} }
await add_afk(user_id, details) 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) await put_cleanmode(message.chat.id, send.id)
@app.on_message(filters.command("afkdel", COMMAND_HANDLER) & filters.group) @app.on_message(filters.command("afkdel", COMMAND_HANDLER) & filters.group)
@ratelimiter @ratelimiter
@adminsOnly("can_change_info") @adminsOnly("can_change_info")
async def afk_state(_, message): @use_chat_lang()
async def afk_state(_, message, strings):
if not message.from_user: if not message.from_user:
return return
usage = "**Usage:**\n/afkdel [ENABLE|DISABLE] to enable or disable auto delete message."
if len(message.command) == 1: 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 chat_id = message.chat.id
state = message.text.split(None, 1)[1].strip() state = message.text.split(None, 1)[1].strip()
state = state.lower() state = state.lower()
if state == "enable": if state == "enable":
await cleanmode_on(chat_id) 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": elif state == "disable":
await cleanmode_off(chat_id) await cleanmode_off(chat_id)
await kirimPesan(message, "Disabled auto delete AFK message.") await kirimPesan(message, strings("afkdel_disable"))
else: 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> 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): async def pling_bypass(url):
try: 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 pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app, user, botStartTime, BOT_NAME 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.helper.human_read import get_readable_file_size, get_readable_time
from misskaty.core.message_utils import editPesan, hapusPesan, kirimPesan from misskaty.core.message_utils import editPesan, hapusPesan, kirimPesan
from misskaty.vars import COMMAND_HANDLER, SUDO 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)) @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""" """Send log file"""
try: try:
await message.reply_document( await message.reply_document(
@ -50,7 +52,7 @@ async def log_file(bot, message):
[ [
[ [
InlineKeyboardButton( InlineKeyboardButton(
"❌ Close", strings("cl_btn"),
f"close#{message.from_user.id}", 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_message(filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_edited_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) @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) cmd = m.text.split(" ", 1)
if len(m.command) == 1: if len(m.command) == 1:
return await edit_or_reply(m, text="No command to execute was given.") return await edit_or_reply(m, text=strings("no_cmd"))
msg = await editPesan(m, "<i>Processing exec pyrogram...</i>") if m.from_user.is_self else await kirimPesan(m, "<i>Processing exec pyrogram...</i>") 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] shell = (await shell_exec(cmd[1]))[0]
if len(shell) > 3000: if len(shell) > 3000:
with open("shell_output.txt", "w") as file: with open("shell_output.txt", "w") as file:
@ -118,7 +121,7 @@ async def shell(_, m):
await m.reply_document( await m.reply_document(
document=doc, document=doc,
file_name=doc.name, 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() await msg.delete()
try: try:
@ -130,22 +133,23 @@ async def shell(_, m):
m, m,
text=shell, text=shell,
parse_mode=enums.ParseMode.HTML, 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: if not m.from_user.is_self:
await msg.delete() await msg.delete()
else: 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_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)) @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) @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()": 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] 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_stderr = sys.stderr
old_stdout = sys.stdout old_stdout = sys.stdout
@ -201,7 +205,7 @@ async def evaluation_cmd_t(_, m):
elif stdout: elif stdout:
evaluation = stdout evaluation = stdout
else: else:
evaluation = "Success" evaluation = strings("success")
final_output = f"**EVAL**:\n`{cmd}`\n\n**OUTPUT**:\n`{evaluation.strip()}`\n" 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>", caption=f"<code>{cmd[1][: 4096 // 4 - 1]}</code>",
disable_notification=True, disable_notification=True,
thumb="assets/thumb.jpg", 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") os.remove("MissKatyEval.txt")
await status_message.delete() await status_message.delete()
@ -222,7 +226,7 @@ async def evaluation_cmd_t(_, m):
m, m,
text=final_output, text=final_output,
parse_mode=enums.ParseMode.MARKDOWN, 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: if not m.from_user.is_self:
await status_message.delete() await status_message.delete()
@ -230,15 +234,16 @@ async def evaluation_cmd_t(_, m):
# Update and restart bot # Update and restart bot
@app.on_message(filters.command(["update"], COMMAND_HANDLER) & filters.user(SUDO)) @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: try:
out = (await shell_exec("git pull"))[0] out = (await shell_exec("git pull"))[0]
if "Already up to date." in str(out): 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>") await message.reply_text(f"<code>{out}</code>")
except Exception as e: except Exception as e:
return await message.reply_text(str(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: with open("restart.pickle", "wb") as status:
pickle.dump([message.chat.id, msg.id], status) pickle.dump([message.chat.id, msg.id], status)
os.execvp(sys.executable, [sys.executable, "-m", "misskaty"]) os.execvp(sys.executable, [sys.executable, "-m", "misskaty"])

View file

@ -159,7 +159,6 @@ async def memify(client, message):
else: else:
await message.reply("Gunakan command <b>/mmf <text></b> dengan reply ke sticker, pisahkan dengan ; untuk membuat posisi text dibawah.") 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)) @app.on_message(filters.command(["dice"], COMMAND_HANDLER))
@use_chat_lang() @use_chat_lang()
async def dice(c, m, strings): async def dice(c, m, strings):

View file

@ -15,10 +15,11 @@ from pyrogram import enums, filters
from pyrogram.errors import FloodWait from pyrogram.errors import FloodWait
from pyrogram.types import InlineKeyboardMarkup 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.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import * 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 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 from misskaty.vars import COMMAND_HANDLER
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
@ -32,40 +33,41 @@ __HELP__ = """"
@app.on_message(filters.command(["genss"], COMMAND_HANDLER)) @app.on_message(filters.command(["genss"], COMMAND_HANDLER))
@ratelimiter @ratelimiter
async def genss(client, m): @use_chat_lang()
async def genss(c, m, strings):
if not m.from_user: if not m.from_user:
return return
replied = m.reply_to_message replied = m.reply_to_message
if len(m.command) == 2 and is_url(m.command[1]): 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]) duration = await get_duration(m.command[1])
if isinstance(duration, str): 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() 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: elif replied and replied.media:
vid = [replied.video, replied.document] vid = [replied.video, replied.document]
media = next((v for v in vid if v is not None), None) media = next((v for v in vid if v is not None), None)
if media is None: if media is None:
return await kirimPesan(m, "Reply to a Telegram Video or document as video to generate screenshoot!", quote=True) return await kirimPesan(m, strings("no_reply"), quote=True)
process = await kirimPesan(m, "<code>Processing, please wait..</code>", quote=True) process = await kirimPesan(m, strings("wait_dl"), quote=True)
if media.file_size > 2097152000: 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() c_time = time.time()
dl = await replied.download( dl = await replied.download(
file_name="/downloads/", file_name="/downloads/",
progress=progress_for_pyrogram, 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)) the_real_download_location = os.path.join("/downloads/", os.path.basename(dl))
if the_real_download_location is not None: if the_real_download_location is not None:
try: 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) await sleep(2)
images = await take_ss(the_real_download_location) images = await take_ss(the_real_download_location)
await editPesan(process, "Mencoba mengupload, hasil generate screenshot..") await editPesan(process, strings("up_progress"))
await client.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO) await c.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO)
try: try:
await gather( await gather(
@ -84,7 +86,7 @@ async def genss(client, m):
) )
await kirimPesan( await kirimPesan(
m, 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, reply_to_message_id=m.id,
) )
await process.delete() await process.delete()
@ -94,14 +96,14 @@ async def genss(client, m):
except: except:
pass pass
except Exception as exc: except Exception as exc:
await kirimPesan(m, f"Gagal generate screenshot.\n\n{exc}") await kirimPesan(m, strings("err_ssgen").format(exc=exc))
try: try:
os.remove(images) os.remove(images)
os.remove(the_real_download_location) os.remove(the_real_download_location)
except: except:
pass pass
else: 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")) @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_positive_group = 3
karma_negative_group = 4 karma_negative_group = 4
regex_upvote = r"^(\+|\+\+|\+1|thx|tnx|ty|thank you|thanx|thanks|pro|cool|good|makasih|👍|\+\+ .+)$" regex_upvote = r"^(\+|\+\+|\+1|thx|tnx|ty|tq|thank you|thanx|thanks|pro|cool|good|agree|makasih|👍|\+\+ .+)$"
regex_downvote = r"^(-|--|-1|👎|-- .+)$" regex_downvote = r"^(-|--|-1|not cool|disagree|worst|bad|👎|-- .+)$"
n = "\n" n = "\n"
w = " " w = " "
bold = lambda x: f"**{x}:** " bold = lambda x: f"**{x}:** "
bold_ul = lambda x: f"**--{x}:**-- " bold_ul = lambda x: f"**--{x}:**-- "
mono = lambda x: f"`{x}`{n}" mono = lambda x: f"`{x}`{n}"
def section( def section(
title: str, title: str,
body: dict, body: dict,
@ -48,18 +46,32 @@ def section(
text = (bold_ul(title) + n) if underline else bold(title) + n text = (bold_ul(title) + n) if underline else bold(title) + n
for key, value in body.items(): 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 return text
async def get_user_id_and_usernames(client) -> dict: async def get_user_id_and_usernames(client) -> dict:
with client.storage.lock, client.storage.conn: with client.storage.lock, client.storage.conn:
users = client.storage.conn.execute('SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null').fetchall() users = client.storage.conn.execute(
return {user[0]: user[3] for user in users} '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( @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, group=karma_positive_group,
) )
@capture_err @capture_err
@ -79,15 +91,25 @@ async def upvote(_, message):
if current_karma: if current_karma:
current_karma = current_karma["karma"] current_karma = current_karma["karma"]
karma = current_karma + 1 karma = current_karma + 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else: else:
karma = 1 karma = 1
new_karma = {"karma": karma} new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_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}") await message.reply_text(
f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
)
@app.on_message( @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, group=karma_negative_group,
) )
@capture_err @capture_err
@ -102,22 +124,37 @@ async def downvote(_, message):
return return
chat_id = message.chat.id 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_id = message.reply_to_message.from_user.id
user_mention = message.reply_to_message.from_user.mention user_mention = message.reply_to_message.from_user.mention
current_karma = await get_karma(chat_id, await int_to_alpha(user_id)) current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
if current_karma: if current_karma:
current_karma = current_karma["karma"] current_karma = current_karma["karma"]
karma = current_karma - 1 karma = current_karma - 1
new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else: else:
karma = 1 karma = 1
new_karma = {"karma": karma} new_karma = {"karma": karma}
await update_karma(chat_id, await int_to_alpha(user_id), new_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}") await message.reply_text(
f"Decremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
)
@app.on_message(filters.command("karma") & filters.group) @app.on_message(filters.command("karma") & filters.group)
@capture_err @capture_err
@ratelimiter
async def command_karma(_, message): async def command_karma(_, message):
chat_id = message.chat.id chat_id = message.chat.id
if not message.reply_to_message: if not message.reply_to_message:
@ -149,22 +186,25 @@ async def command_karma(_, message):
if int(user_idd) not in list(userdb.keys()): if int(user_idd) not in list(userdb.keys()):
continue continue
username = userdb[int(user_idd)] username = userdb[int(user_idd)]
karma[f"@{username}"] = [f"**{str(karma_count)}**"] karma["@" + username] = ["**" + str(karma_count) + "**"]
limit += 1 limit += 1
await m.edit(section(msg, karma)) await m.edit(section(msg, karma))
else: else:
if not message.reply_to_message.from_user: 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 user_id = message.reply_to_message.from_user.id
karma = await get_karma(chat_id, await int_to_alpha(user_id)) karma = await get_karma(chat_id, await int_to_alpha(user_id))
karma = karma["karma"] if karma else 0 if karma:
await message.reply_text(f"**Total Points**: __{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) @app.on_message(filters.command("karma_toggle") & ~filters.private)
@adminsOnly @adminsOnly("can_change_info")
@ratelimiter
async def captcha_state(_, message): async def captcha_state(_, message):
usage = "**Usage:**\n/karma_toggle [ENABLE|DISABLE]" usage = "**Usage:**\n/karma_toggle [ENABLE|DISABLE]"
if len(message.command) != 2: if len(message.command) != 2:
@ -174,9 +214,9 @@ async def captcha_state(_, message):
state = state.lower() state = state.lower()
if state == "enable": if state == "enable":
await karma_on(chat_id) 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": elif state == "disable":
await karma_off(chat_id) await karma_off(chat_id)
await message.reply_text("Disabled karma system.") await message.reply_text("Disabled Karma System for this chat.")
else: else:
await message.reply_text(usage) await message.reply_text(usage)

View file

@ -56,11 +56,11 @@ DETAILS
file_info.message_type file_info.message_type
try: try:
link = await mediainfo_paste(out, "MissKaty Mediainfo") link = await mediainfo_paste(out, "MissKaty Mediainfo")
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]]) markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except: except:
try: try:
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text) 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: except:
markup = None markup = None
with io.BytesIO(str.encode(body_text)) as out_file: with io.BytesIO(str.encode(body_text)) as out_file:
@ -91,11 +91,11 @@ DETAILS
# link = await post_to_telegraph(False, title, body_text) # link = await post_to_telegraph(False, title, body_text)
try: try:
link = await mediainfo_paste(out, "MissKaty Mediainfo") link = await mediainfo_paste(out, "MissKaty Mediainfo")
markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]]) markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except: except:
try: try:
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text) 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: except:
markup = None markup = None
with io.BytesIO(str.encode(output)) as out_file: 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.errors import ChannelInvalid, ChannelPrivate, ChatAdminRequired, ChatNotModified
from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup 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.message_utils import *
from misskaty.core.decorator.ratelimiter import ratelimiter 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 from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, TZ
__MODULE__ = "NightMode" __MODULE__ = "NightMode"
@ -85,46 +87,49 @@ def extract_time(time_val: str):
async def un_mute_chat(chat_id: int, perm: ChatPermissions): async def un_mute_chat(chat_id: int, perm: ChatPermissions):
getlang = await get_db_lang(chat_id)
try: try:
await app.set_chat_permissions(chat_id, perm) await app.set_chat_permissions(chat_id, perm)
except ChatAdminRequired: 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): except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}") scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_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: except ChatNotModified:
pass pass
except Exception as e: 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: else:
job = scheduler.get_job(f"enable_nightmode_{chat_id}") job = scheduler.get_job(f"enable_nightmode_{chat_id}")
close_at = job.next_run_time 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): async def mute_chat(chat_id: int):
getlang = await get_db_lang(chat_id)
try: try:
await app.set_chat_permissions(chat_id, ChatPermissions()) await app.set_chat_permissions(chat_id, ChatPermissions())
except ChatAdminRequired: 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): except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}") scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_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: except ChatNotModified:
pass pass
except Exception as e: 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: else:
job = scheduler.get_job(f"disable_nightmode_{chat_id}") job = scheduler.get_job(f"disable_nightmode_{chat_id}")
open_at = job.next_run_time 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) @app.on_message(filters.command("nightmode", COMMAND_HANDLER) & filters.group)
@adminsOnly("can_change_info") @require_admin(permissions=["can_change_info"])
async def nightmode_handler(c, msg): @use_chat_lang()
async def nightmode_handler(c, msg, strings):
chat_id = msg.chat.id chat_id = msg.chat.id
if "-d" in msg.text: 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}") scheduler.remove_job(job_id=f"disable_nightmode_{chat_id}")
if not bool(scheduler.get_jobs()) and bool(scheduler.state): if not bool(scheduler.get_jobs()) and bool(scheduler.state):
scheduler.shutdown() scheduler.shutdown()
return await kirimPesan(msg, "Nightmode disabled.") return await kirimPesan(msg, strings("nmd_disabled"))
return await kirimPesan(msg, "Nightmode isn't enabled in this chat.") return await kirimPesan(msg, strings("nmd_not_enabled"))
starttime = re.findall(r"-s=(\d+:\d+)", msg.text) starttime = re.findall(r"-s=(\d+:\d+)", msg.text)
start = starttime[0] if starttime else "00:00" start = starttime[0] if starttime else "00:00"
@ -144,13 +149,13 @@ async def nightmode_handler(c, msg):
try: try:
start_timestamp = TIME_ZONE.localize(datetime.strptime((now.strftime("%m:%d:%Y - ") + start), "%m:%d:%Y - %H:%M")) start_timestamp = TIME_ZONE.localize(datetime.strptime((now.strftime("%m:%d:%Y - ") + start), "%m:%d:%Y - %H:%M"))
except ValueError: 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 = re.findall(r"-e=(\w+)", msg.text)
lockdur = lockdur[0] if lockdur else "6h" lockdur = lockdur[0] if lockdur else "6h"
lock_dur = extract_time(lockdur.lower()) lock_dur = extract_time(lockdur.lower())
if not lock_dur: 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: if start_timestamp < now:
start_timestamp = start_timestamp + timedelta(days=1) start_timestamp = start_timestamp + timedelta(days=1)
@ -162,13 +167,14 @@ async def nightmode_handler(c, msg):
# schedule to disable nightmode # schedule to disable nightmode
scheduler.add_job(un_mute_chat, "interval", [chat_id, msg.chat.permissions], id=f"disable_nightmode_{chat_id}", days=1, next_run_time=end_time_stamp, max_instances=50, misfire_grace_time=None) scheduler.add_job(un_mute_chat, "interval", [chat_id, msg.chat.permissions], id=f"disable_nightmode_{chat_id}", days=1, next_run_time=end_time_stamp, max_instances=50, misfire_grace_time=None)
except ConflictingIdError: except ConflictingIdError:
return await kirimPesan(msg, "Already a schedule is running in this chat. Disable it using `-d` flag.") return await kirimPesan(msg, strings("schedule_already_on"))
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.") await kirimPesan(msg, strings("nmd_enable_success").format(st=start_timestamp.strftime("%H:%M:%S"), lockdur=lockdur))
if not bool(scheduler.state): if not bool(scheduler.state):
scheduler.start() scheduler.start()
@app.on_callback_query(filters.regex(r"^nightmd$")) @app.on_callback_query(filters.regex(r"^nightmd$"))
@ratelimiter @ratelimiter
async def callbackanightmd(c, q): @use_chat_lang()
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) 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 from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "OCR" __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)) @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.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http from misskaty.helper.http import http
from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
LOGGER = getLogger(__name__) LOGGER = getLogger(__name__)
@ -25,23 +26,21 @@ def rand_key():
@app.on_message(filters.command(["ytsearch"], COMMAND_HANDLER) & ~filters.channel) @app.on_message(filters.command(["ytsearch"], COMMAND_HANDLER) & ~filters.channel)
@capture_err @capture_err
@ratelimiter @ratelimiter
async def ytsearch(_, message): @use_chat_lang()
async def ytsearch(_, message, strings):
if message.sender_chat: 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: 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] query = message.text.split(" ", maxsplit=1)[1]
search_key = rand_key() search_key = rand_key()
YT_DB[search_key] = query YT_DB[search_key] = query
search = await main.VideosSearch(query).next() search = await main.VideosSearch(query).next()
if search["result"] == []: 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] i = search["result"][0]
out = f"<b><a href={i['link']}>{i['title']}</a></b>" out = f"<b><a href={i['link']}>{i['title']}</a></b>\n"
out += f"\nPublished {i['publishedTime']}\n" out = strings("yts_msg").format(pub=i['publishedTime'], dur=i['duration'], vi=i['viewCount']['short'], clink=i['channel']['link'], cname=i['channel']['name'])
out += 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"
btn = InlineKeyboardMarkup( btn = InlineKeyboardMarkup(
[ [
[ [
@ -50,7 +49,7 @@ async def ytsearch(_, message):
callback_data=f"ytdl_scroll|{search_key}|1", 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"]) img = await get_ytthumb(i["id"])
@ -62,17 +61,18 @@ async def ytsearch(_, message):
@app.on_message(filters.command(["ytdown"], COMMAND_HANDLER)) @app.on_message(filters.command(["ytdown"], COMMAND_HANDLER))
@capture_err @capture_err
@ratelimiter @ratelimiter
async def ytdownv2(_, message): @use_chat_lang()
async def ytdownv2(_, message, strings):
if not message.from_user: if not message.from_user:
return return await kirimPesan(message, strings("no_channel"))
if len(message.command) == 1: 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] url = message.text.split(" ", maxsplit=1)[1]
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl: async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
try: try:
x = await ytdl.parse(url) x = await ytdl.parse(url)
if x is None: 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) img = await get_ytthumb(x.key)
caption = x.caption caption = x.caption
markup = x.buttons markup = x.buttons
@ -83,9 +83,10 @@ async def ytdownv2(_, message):
@app.on_callback_query(filters.regex(r"^yt_listall")) @app.on_callback_query(filters.regex(r"^yt_listall"))
@ratelimiter @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: 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("|") callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl: async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
media, buttons = await ytdl.listview(callback[1]) 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")) @app.on_callback_query(filters.regex(r"^yt_extract_info"))
@ratelimiter @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: 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)
await cq.answer("Please Wait...") await cq.answer(strings("wait"))
callback = cq.data.split("|") callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl: 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]): 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)")) @app.on_callback_query(filters.regex(r"^yt_(gen|dl)"))
@ratelimiter @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: 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("|") callback = cq.data.split("|")
key = callback[1] key = callback[1]
if callback[0] == "yt_gen": 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")) @app.on_callback_query(filters.regex(r"^ytdl_scroll"))
@ratelimiter @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: 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("|") callback = cq.data.split("|")
search_key = callback[1] search_key = callback[1]
page = int(callback[2]) page = int(callback[2])
@ -180,13 +184,10 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery):
search = await main.VideosSearch(query).next() search = await main.VideosSearch(query).next()
i = search["result"][page] i = search["result"][page]
out = f"<b><a href={i['link']}>{i['title']}</a></b>" out = f"<b><a href={i['link']}>{i['title']}</a></b>"
out += f"\nPublished {i['publishedTime']}\n" out = strings("yts_msg").format(pub=i['publishedTime'], dur=i['duration'], vi=i['viewCount']['short'], clink=i['channel']['link'], cname=i['channel']['name'])
out += 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"
scroll_btn = [ 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( InlineKeyboardButton(
f"{page+1}/{len(search['result'])}", f"{page+1}/{len(search['result'])}",
callback_data=f"ytdl_scroll|{search_key}|{page+1}", callback_data=f"ytdl_scroll|{search_key}|{page+1}",
@ -195,11 +196,11 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery):
] ]
if page == 0: if page == 0:
if len(search["result"]) == 1: 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()]] scroll_btn = [[scroll_btn.pop().pop()]]
elif page == (len(search["result"]) - 1): elif page == (len(search["result"]) - 1):
scroll_btn = [[scroll_btn.pop().pop(0)]] 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) btn = InlineKeyboardMarkup(scroll_btn + btn)
await cq.edit_message_media(InputMediaPhoto(await get_ytthumb(i["id"]), caption=out), reply_markup=btn) await cq.edit_message_media(InputMediaPhoto(await get_ytthumb(i["id"]), caption=out), reply_markup=btn)