From 83b04d76b5a3bf1b89bfe46b2e52e5fc1a77b9a0 Mon Sep 17 00:00:00 2001
From: yasirarism <55983182+yasirarism@users.noreply.github.com>
Date: Sat, 1 Apr 2023 12:06:47 +0700
Subject: [PATCH] Beta MultiLang (#26)
---
database/karma_db.py | 4 +-
database/locale_db.py | 2 +-
locales/en-US/admin.json | 2 +-
locales/en-US/afk.json | 13 +
locales/en-US/dev.json | 11 +
locales/en-US/genss.json | 13 +
locales/en-US/nightmodev2.json | 17 +
locales/en-US/start_help.json | 11 +
locales/en-US/web_scraper.json | 19 +-
locales/en-US/ytdl_plugins.json | 13 +
locales/id-ID/admin.json | 26 +-
locales/id-ID/afk.json | 13 +
locales/id-ID/chatbot_ai.json | 4 +-
locales/id-ID/dev.json | 11 +
locales/id-ID/genss.json | 13 +
locales/id-ID/lang_setting.json | 2 +-
locales/id-ID/mediainfo.json | 6 +-
locales/id-ID/nightmodev2.json | 17 +
locales/id-ID/start_help.json | 11 +
locales/id-ID/stickers.json | 2 +-
locales/id-ID/web_scraper.json | 19 +-
locales/id-ID/ytdl_plugins.json | 13 +
locales/id-JW/admin.json | 12 +-
locales/id-JW/afk.json | 13 +
locales/id-JW/chatbot_ai.json | 4 +-
locales/id-JW/dev.json | 11 +
locales/id-JW/genss.json | 13 +
locales/id-JW/mediainfo.json | 6 +-
locales/id-JW/nightmodev2.json | 17 +
locales/id-JW/start_help.json | 11 +
locales/id-JW/stickers.json | 2 +-
locales/id-JW/web_scraper.json | 19 +-
locales/id-JW/ytdl_plugins.json | 13 +
misskaty/__main__.py | 299 +-------------
misskaty/core/decorator/permissions.py | 42 +-
misskaty/helper/localization.py | 2 +-
misskaty/plugins/admin.py | 56 +--
misskaty/plugins/afk.py | 252 +++++++++++-
misskaty/plugins/bypass.py | 1 +
misskaty/plugins/detect_afk.py | 234 -----------
misskaty/plugins/dev.py | 39 +-
misskaty/plugins/fun.py | 1 -
misskaty/plugins/genss.py | 32 +-
misskaty/plugins/karma.py | 92 +++--
misskaty/plugins/mediainfo.py | 8 +-
misskaty/plugins/nightmodev2.py | 46 ++-
misskaty/plugins/ocr.py | 2 +-
misskaty/plugins/start_help.py | 292 ++++++++++++++
misskaty/plugins/web_scraper.py | 375 ++++++++++--------
.../{ytdl_download_new.py => ytdl_plugins.py} | 61 +--
50 files changed, 1296 insertions(+), 901 deletions(-)
create mode 100644 locales/en-US/afk.json
create mode 100644 locales/en-US/dev.json
create mode 100644 locales/en-US/genss.json
create mode 100644 locales/en-US/nightmodev2.json
create mode 100644 locales/en-US/start_help.json
create mode 100644 locales/en-US/ytdl_plugins.json
create mode 100644 locales/id-ID/afk.json
create mode 100644 locales/id-ID/dev.json
create mode 100644 locales/id-ID/genss.json
create mode 100644 locales/id-ID/nightmodev2.json
create mode 100644 locales/id-ID/start_help.json
create mode 100644 locales/id-ID/ytdl_plugins.json
create mode 100644 locales/id-JW/afk.json
create mode 100644 locales/id-JW/dev.json
create mode 100644 locales/id-JW/genss.json
create mode 100644 locales/id-JW/nightmodev2.json
create mode 100644 locales/id-JW/start_help.json
create mode 100644 locales/id-JW/ytdl_plugins.json
delete mode 100644 misskaty/plugins/detect_afk.py
create mode 100644 misskaty/plugins/start_help.py
rename misskaty/plugins/{ytdl_download_new.py => ytdl_plugins.py} (78%)
diff --git a/database/karma_db.py b/database/karma_db.py
index 0ef04570..2d6ff454 100644
--- a/database/karma_db.py
+++ b/database/karma_db.py
@@ -48,7 +48,9 @@ async def update_karma(chat_id: int, name: str, karma: dict):
async def is_karma_on(chat_id: int) -> bool:
chat = await karmadb.find_one({"chat_id_toggle": chat_id})
- return bool(chat)
+ if not chat:
+ return True
+ return False
async def karma_on(chat_id: int):
diff --git a/database/locale_db.py b/database/locale_db.py
index d8385dff..e81dd0f3 100644
--- a/database/locale_db.py
+++ b/database/locale_db.py
@@ -11,6 +11,6 @@ async def set_db_lang(chat_id: int, chat_type: str, lang_code: str):
await localesdb.update_one({"chat_id": chat_id}, {"$set": {"lang": lang_code, "chat_type": chat_type.value}}, upsert=True)
-async def get_db_lang(chat_id: int, chat_type: str) -> str:
+async def get_db_lang(chat_id: int) -> str:
ul = await localesdb.find_one({"chat_id": chat_id})
return ul["lang"] if ul else {}
diff --git a/locales/en-US/admin.json b/locales/en-US/admin.json
index 161af3d3..8470d1ee 100644
--- a/locales/en-US/admin.json
+++ b/locales/en-US/admin.json
@@ -1,7 +1,7 @@
{
"no_admin_error": "You must be an administrator to use this command.",
"no_permission_error": "I'm sorry but you don't have the required permissions to run this command. Missing permissions: {permissions}",
- "private_not_allowed": "This command can't be used in a private chat. If you need any help, please use the /help command.",
+ "private_not_allowed": "This command can't be used in a private chat. If you need any help, please use the /help command.",
"purge_no_reply": "Reply to a message to purge from.",
"delete_no_reply": "Reply To A Message To Delete It",
"pin_no_reply": "Reply to a message to pin/unpin it.",
diff --git a/locales/en-US/afk.json b/locales/en-US/afk.json
new file mode 100644
index 00000000..bdd7f0f7
--- /dev/null
+++ b/locales/en-US/afk.json
@@ -0,0 +1,13 @@
+{
+ "no_channel": "This feature not supported for channel.",
+ "on_afk_msg_no_r": "**{usr}** [{id}] is back online and was away for {tm}\n\n",
+ "on_afk_msg_with_r": "**{usr}** [{id}] is back online and was away for {tm}\n\n**Reason:** `{reas}`\n\n",
+ "is_afk_msg_no_r": "**{usr}** [{id}] is AFK since {tm} ago.\n\n",
+ "is_afk_msg_with_r": "**{usr}** [{id}] is AFK since {tm} ago.\n\n**Reason:** {reas}\n\n",
+ "is_online": "**{usr}** [{id}] is back online",
+ "now_afk": "{usr} [{id}] 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} [{id}] is AFK!."
+}
\ No newline at end of file
diff --git a/locales/en-US/dev.json b/locales/en-US/dev.json
new file mode 100644
index 00000000..111ef725
--- /dev/null
+++ b/locales/en-US/dev.json
@@ -0,0 +1,11 @@
+{
+ "already_up": "Its already up-to date!",
+ "up_and_rest": "Updated with default branch, restarting now.",
+ "cl_btn": "β Close",
+ "no_eval": "__No evaluate message!__",
+ "run_eval": "Processing eval pyrogram..",
+ "run_exec": "Processing exec pyrogram..",
+ "no_cmd": "No command to execute was given.",
+ "success": "Success",
+ "no_reply": "No Reply"
+}
\ No newline at end of file
diff --git a/locales/en-US/genss.json b/locales/en-US/genss.json
new file mode 100644
index 00000000..964ea1c1
--- /dev/null
+++ b/locales/en-US/genss.json
@@ -0,0 +1,13 @@
+{
+ "wait_msg": "Give me some time to process your request!! π΄",
+ "wait_dl": "Processing, please wait..",
+ "dl_progress": "Trying to download, please wait..",
+ "up_progress": "Trying to upload...",
+ "success_dl_msg": "File has been downloaded to {path}.",
+ "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} ({id})\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`)"
+}
\ No newline at end of file
diff --git a/locales/en-US/nightmodev2.json b/locales/en-US/nightmodev2.json
new file mode 100644
index 00000000..d952bc8f
--- /dev/null
+++ b/locales/en-US/nightmodev2.json
@@ -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}"
+}
\ No newline at end of file
diff --git a/locales/en-US/start_help.json b/locales/en-US/start_help.json
new file mode 100644
index 00000000..adf6384d
--- /dev/null
+++ b/locales/en-US/start_help.json
@@ -0,0 +1,11 @@
+{
+ "newgroup_log": "#NewGroup\nGroup = {jdl}({id})\nMembers Count = {c}",
+ "newuser_log": "#NewUser\nID - {id}\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."
+}
\ No newline at end of file
diff --git a/locales/en-US/web_scraper.json b/locales/en-US/web_scraper.json
index 9e26dfee..d364a6ee 100644
--- a/locales/en-US/web_scraper.json
+++ b/locales/en-US/web_scraper.json
@@ -1 +1,18 @@
-{}
\ No newline at end of file
+{
+ "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": "Scrape result from {link}:\n\n{kl}",
+ "header_with_query": "#{web} Results For: {kueri}\n\n",
+ "header_no_query": "#{web} Latest:\nπ Use /{cmd} [title] to start search with title.\n\n",
+ "invalid_cmd_scrape": "Gunakan command /{cmd} [link] untuk scrap link download",
+ "unsupport_dl_btn": "Some result will not appear in extract button because unsupported link."
+}
\ No newline at end of file
diff --git a/locales/en-US/ytdl_plugins.json b/locales/en-US/ytdl_plugins.json
new file mode 100644
index 00000000..85f2269a
--- /dev/null
+++ b/locales/en-US/ytdl_plugins.json
@@ -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β― Duration: {dur}\nβ― Views: {vi}\nβ― Uploader: {cname}\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"
+}
\ No newline at end of file
diff --git a/locales/id-ID/admin.json b/locales/id-ID/admin.json
index 2b2af807..dcd08954 100644
--- a/locales/id-ID/admin.json
+++ b/locales/id-ID/admin.json
@@ -1,8 +1,8 @@
{
- "no_admin_error": "Anda harus merupakan administrator untuk menggunakan perintah ini.",
+ "no_admin_error": "Anda harus menjadi administrator untuk menggunakan perintah ini.",
"no_permission_error": "Maaf, tapi anda tidak memiliki izin yang diperlukan untuk menjalankan perintah ini. Izin yang hilang: {permissions}",
- "private_not_allowed": "Perintah ini tidak dapat digunakan dalam obrolan pribadi, Jika anda membutuhkan bantuan, mohon gunakan perintah /help.",
- "purge_no_reply": "Balas pesan untuk dihapus.",
+ "private_not_allowed": "Perintah ini tidak dapat digunakan dalam obrolan pribadi, Jika anda membutuhkan bantuan, mohon gunakan perintah /help.",
+ "purge_no_reply": "Balas ke pesan yang ingin dihapus.",
"delete_no_reply": "Balas Pesan Untuk Menghapusnya",
"pin_no_reply": "Balas pesan untuk menyematkan/melepas pin.",
"report_no_reply": "Balas Pesan Untuk Melaporkan Pengguna Itu.",
@@ -13,12 +13,12 @@
"kick_self_err": "Saya tidak dapat menendang diri sendiri, saya dapat pergi jika Anda mau.",
"ban_self_err": "Saya tidak dapat melarang diri saya sendiri, saya dapat pergi jika Anda mau.",
"report_self_err": "Mengapa Anda melaporkan diri sendiri?",
- "demote_self_err": "Saya tidak dapat menurunkan pangkat diri saya sendiri.",
+ "demote_self_err": "Saya tidak dapat menurunkan keanggotaan diri saya sendiri.",
"warn_self_err": "Saya tidak dapat memperingatkan diri sendiri.",
- "mute_self_err": "Saya sendiri tidak dapat membisukan.",
- "kick_sudo_err": "Wow, Anda ingin menendang pemilik saya?",
- "ban_sudo_err": "Wow, Anda ingin mencoba mencekal pemilik saya?",
- "demote_sudo_err": "Wow, Anda ingin mencoba menurunkan pemilik saya?",
+ "mute_self_err": "Saya tidak dapat membisukan diri sendiri.",
+ "kick_sudo_err": "Wow, Anda ingin menendang pemilik saya yang spesial?",
+ "ban_sudo_err": "Wow, Anda ingin mencoba membanned pemilik saya?",
+ "demote_sudo_err": "Wow, Anda ingin mencoba mendemote pemilik saya?",
"warn_sudo_err": "Wow, Anda ingin mencoba memberi peringatan kepada pemilik saya?",
"mute_sudo_err": "Wow, Anda ingin mencoba membisukan pemilik saya?",
"kick_admin_err": "Hah, sungguh gila jika saya bisa menendang seorang admin.",
@@ -28,13 +28,13 @@
"kick_msg": "**Pengguna yang Ditendang:** {mention} [{id}]\n**Ditendang Oleh:** {kicker}\n**Alasan:** {reasonmsg}",
"ban_msg": "**Pengguna yang Dilarang:** {mention} [{id}]\n**Dilarang Oleh:** {banner}\n",
"unban_msg": "__Banned dihapus oleh {mention}__",
- "no_ban_permission": "Tolong beri saya izin larangan untuk melarang pengguna di grup ini.",
+ "no_ban_permission": "Tolong beri saya izin banned untuk membanned pengguna di grup ini.",
"no_more_99": "Anda tidak dapat menggunakan lebih dari 99",
"banned_time": "**Dilarang Untuk:** {val}\n",
- "muted_time": "**Dimatikan Untuk:** {val}\n",
+ "muted_time": "**Dimute Untuk:** {val}\n",
"banned_reason": "**Alasan:** {reas}",
"unban_channel_err": "Anda tidak dapat membatalkan pemblokiran saluran",
- "give_unban_user": "Berikan nama pengguna atau balas pesan pengguna untuk membatalkan larangan.",
+ "give_unban_user": "Berikan nama pengguna atau balas pesan pengguna untuk membatalkan banned.",
"unban_success": "Berhasil membatalkan pemblokiran {umention}!",
"give_idban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan pelarangan daftar",
"give_idunban_with_msg_link": "Berikan userid/nama pengguna beserta tautan pesan dan alasan untuk membatalkan larangan",
@@ -55,7 +55,7 @@
"report_msg": "Melaporkan {user_mention} ke admin!",
"reported_is_admin": "Apakah Anda tahu bahwa pengguna yang Anda balas adalah seorang admin?",
"user_no_warn": "Pengguna {mention} tidak memiliki peringatan.",
- "ch_warn_msg": "User {mention} memiliki {warns}/3 peringatan.",
+ "ch_warn_msg": "Pengguna {mention} memiliki {warns}/3 peringatan.",
"warn_msg": "**Pengguna yang Diperingatkan:** {mention}\n**Diperingatkan Oleh:** {warner}\n**Alasan:** {reas}\n**Peringatan:** {twarn}/ 3",
"rmwarn_msg": "Peringatan {mention} telah dihapus.",
"unwarn_msg": "Peringatan dihapus oleh {mention}.",
@@ -63,6 +63,6 @@
"unmute_msg": "Disuarakan! {umention}",
"reply_to_rm_warn": "Balas pesan untuk menghapus peringatan pengguna.",
"exceed_warn_msg": "Jumlah peringatan dari {mention} terlampaui, DILARANG!",
- "mute_msg": "**Pengguna yang Dibungkam:** {mention}\n**Dimatikan Oleh:** {muter}\n",
+ "mute_msg": "**Pengguna yang Dimute:** {mention}\n**Dimute Oleh:** {muter}\n",
"rm_warn_btn": "π¨ Hapus Peringatan π¨"
}
diff --git a/locales/id-ID/afk.json b/locales/id-ID/afk.json
new file mode 100644
index 00000000..7ca88cb2
--- /dev/null
+++ b/locales/id-ID/afk.json
@@ -0,0 +1,13 @@
+{
+ "no_channel": "Fitur ini tidak didukung untuk channel.",
+ "on_afk_msg_no_r": "**{usr}** [{id}] kembali online dan pergi selama {tm}\n\n",
+ "on_afk_msg_with_r": "**{usr}** [{id}] kembali online dan pergi untuk {tm}\n\n**Alasan:** `{reas}`\n\n",
+ "is_afk_msg_no_r": "**{usr}** [{id}] telah AFK sejak {tm} yang lalu.\n\n",
+ "is_afk_msg_with_r": "**{usr}** [{id}] telah AFK sejak {tm} yang lalu.\n\n**Alasan:** {reas}\n\n" ,
+ "is_online": "**{usr}** [{id}] kembali online",
+ "now_afk": "{usr} [{id}] 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} [{id}] sedang AFK!."
+}
\ No newline at end of file
diff --git a/locales/id-ID/chatbot_ai.json b/locales/id-ID/chatbot_ai.json
index 266270fb..5080d9a4 100644
--- a/locales/id-ID/chatbot_ai.json
+++ b/locales/id-ID/chatbot_ai.json
@@ -1,5 +1,5 @@
{
- "no_question": "Harap gunakan perintah /{cmd} [question] untuk mengajukan pertanyaan Anda.",
- "find_answers_str": "Tunggu sebentar untuk mencari jawaban Anda..",
+ "no_question": "Harap gunakan perintah /{cmd} [question] untuk mengajukan pertanyaan Anda menggunakan OpenAI.",
+ "find_answers_str": "Sedang mencari jawaban terbaik buat Anda..",
"answers_too_long": "Pertanyaan untuk jawaban Anda telah melampaui batas teks TG, periksa tautan ini untuk melihatnya.\n\n{answerlink}"
}
\ No newline at end of file
diff --git a/locales/id-ID/dev.json b/locales/id-ID/dev.json
new file mode 100644
index 00000000..f2e855e6
--- /dev/null
+++ b/locales/id-ID/dev.json
@@ -0,0 +1,11 @@
+{
+ "already_up": "Sudah paling update!",
+ "up_and_rest": "Diperbarui dengan branch default, dimulai ulang sekarang.",
+ "cl_btn": "β Tutup",
+ "no_eval": "__Tidak ada pesan eval!__",
+ "run_eval": "Memproses pyrogram eval..",
+ "run_exec": "Memproses pyrogram eksekutif..",
+ "no_cmd": "Tidak ada perintah untuk dieksekusi.",
+ "sukses": "Sukses",
+ "no_reply": "Tidak ada balasan"
+}
\ No newline at end of file
diff --git a/locales/id-ID/genss.json b/locales/id-ID/genss.json
new file mode 100644
index 00000000..980b0522
--- /dev/null
+++ b/locales/id-ID/genss.json
@@ -0,0 +1,13 @@
+{
+ "wait_msg": "Beri saya waktu untuk memproses permintaan Anda!! π΄",
+ "wait_dl": "Sedang diproses, harap tunggu..",
+ "dl_progress": "Mencoba mengunduh, harap tunggu..",
+ "up_progress": "Mencoba mengunggah...",
+ "success_dl_msg": "Berkas telah diunduh ke {path}.",
+ "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} ({id})\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`)"
+}
\ No newline at end of file
diff --git a/locales/id-ID/lang_setting.json b/locales/id-ID/lang_setting.json
index 7c70197e..bae662bf 100644
--- a/locales/id-ID/lang_setting.json
+++ b/locales/id-ID/lang_setting.json
@@ -1,5 +1,5 @@
{
"language_changed_successfully": "Bahasa telah berhasil diubah.",
"language_changer_chat": "Di sini Anda dapat mengubah bahasa yang digunakan bot selama obrolan.\nJika bahasa Anda tidak ada di sini dan Anda ingin berkontribusi, Anda dapat membuka masalah di github saya. .",
- "language_changer_private": "Di sini Anda dapat mengubah bahasa yang digunakan oleh bot dalam obrolan pribadi ini.\n\nJika Anda ingin mengubah bahasa grup Anda, buka perintah /setchatlang. \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 /setchatlang. \nJika bahasa Anda tidak ada di sini dan Anda ingin berkontribusi, buka repo misskaty di github."
}
\ No newline at end of file
diff --git a/locales/id-ID/mediainfo.json b/locales/id-ID/mediainfo.json
index 74ee7ade..6c719fec 100644
--- a/locales/id-ID/mediainfo.json
+++ b/locales/id-ID/mediainfo.json
@@ -3,9 +3,9 @@
"wait_msg": "`Mohon tunggu sementara...`",
"err_link": "Sepertinya tautan yang Anda kirim tidak valid, pastikan tautan langsung dan bisa di unduh.",
"media_invalid": "Silakan balas ke media yang valid.",
- "dl_limit_exceeded": "Maaf, unduh dibatasi hingga 2GB untuk mengurangi banjir. Anda dapat mengonversi berkas Anda menjadi tautan.",
+ "dl_limit_exceeded": "Maaf, unduh dibatasi hingga 2GB untuk mengurangi flood. Anda dapat mengonversi berkas Anda menjadi tautan.",
"dl_args_text": "Mencoba mengunduh..",
"mediainfo_help": "Gunakan perintah /{cmd} [tautan], atau balas telegram media dengan /{cmd}.",
- "capt_media": "βΉοΈ Hasil mediainfo anda..\n\n**Request Oleh:** {ment}",
- "viewweb": "π¬ Buka di Web"
+ "capt_media": "βΉοΈ Hasil mediainfo anda..\n\n**Diminta Oleh:** {ment}",
+ "viweb": "π¬ Buka di Web"
}
\ No newline at end of file
diff --git a/locales/id-ID/nightmodev2.json b/locales/id-ID/nightmodev2.json
new file mode 100644
index 00000000..f8cf223d
--- /dev/null
+++ b/locales/id-ID/nightmodev2.json
@@ -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}"
+}
\ No newline at end of file
diff --git a/locales/id-ID/start_help.json b/locales/id-ID/start_help.json
new file mode 100644
index 00000000..2919aa50
--- /dev/null
+++ b/locales/id-ID/start_help.json
@@ -0,0 +1,11 @@
+{
+ "newgroup_log": "#NewGroup\nGroup = {jdl}({id})\nJumlah Anggota = {c}",
+ "newuser_log": "#PenggunaBaru\nID - {id}\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."
+}
\ No newline at end of file
diff --git a/locales/id-ID/stickers.json b/locales/id-ID/stickers.json
index 82869f12..cd69b711 100644
--- a/locales/id-ID/stickers.json
+++ b/locales/id-ID/stickers.json
@@ -14,6 +14,6 @@
"please_start_msg": "Tampaknya Anda belum pernah berinteraksi dengan saya dalam obrolan pribadi, Anda harus melakukannya dulu..",
"click_me": "Klik Saya",
"pack_full": "Paket Stiker Anda penuh jika paket Anda tidak dalam Tipe v1 /kang 1, jika tidak dalam Tipe v2 /kang 2 dan seterusnya.",
- "viewpack": "π Lihat Paket Anda",
+ "viewpack": "π Lihat Paket",
"kang_success": "Stiker berhasil dicuri!\nEmoji: {emot}"
}
\ No newline at end of file
diff --git a/locales/id-ID/web_scraper.json b/locales/id-ID/web_scraper.json
index 9e26dfee..fc77e00d 100644
--- a/locales/id-ID/web_scraper.json
+++ b/locales/id-ID/web_scraper.json
@@ -1 +1,18 @@
-{}
\ No newline at end of file
+{
+ "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": "Hasil Scrape dari {link}:\n\n{kl}",
+ "header_with_query": "Hasil Pencarian #{web} Untuk: {kueri}\n\n",
+ "header_no_query": "#{web} Terbaru:\nπ Gunakan /{cmd} [judul] untuk memulai pencarian dengan judul.\n\n",
+ "invalid_cmd_scrape": "Gunakan perintah /{cmd} [tautan] untuk mengambil link unduhan.",
+ "unsupport_dl_btn": "Beberapa hasil tidak akan muncul di tombol ekstrak karena tautan tidak didukung."
+}
\ No newline at end of file
diff --git a/locales/id-ID/ytdl_plugins.json b/locales/id-ID/ytdl_plugins.json
new file mode 100644
index 00000000..88605d0b
--- /dev/null
+++ b/locales/id-ID/ytdl_plugins.json
@@ -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β― Durasi: {dur}\nβ― Penayangan: {vi}\nβ― Pengunggah:< /b> {cname}\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"
+}
\ No newline at end of file
diff --git a/locales/id-JW/admin.json b/locales/id-JW/admin.json
index 2c944aa6..ed529ee6 100644
--- a/locales/id-JW/admin.json
+++ b/locales/id-JW/admin.json
@@ -1,21 +1,21 @@
{
"no_admin_error": "Sampeyan kudu dadi administrator kanggo nggunakake perintah iki.",
- "no_permission_error": "Ngapunten, nanging sampeyan ora duwe idin sing dibutuhake kanggo nindakake perintah iki. Izin sing ilang: {idin}",
- "private_not_allowed": "Perintah iki ora bisa digunakake ing obrolan pribadi, Yen sampeyan butuh bantuan, mohon nggunakake perintah /help.",
+ "no_permission_error": "Ngapunten, nanging sampeyan ora duwe izin sing dibutuhake kanggo nindakake perintah iki. Izin sing ilang: {permissions}",
+ "private_not_allowed": "Perintah iki ora bisa digunakake ing obrolan pribadi, Yen sampeyan butuh bantuan, mohon nggunakake perintah /help.",
"purge_no_reply": "Bales pesen sing arep dibusak.",
"delete_no_reply": "Bales Pesen Kanggo Mbusak",
"pin_no_reply": "Bales pesen sing arep disematke/copot.",
"report_no_reply": "Bales Pesen Kanggo Nglaporake Panganggo.",
- "no_delete_perm": "Tulung aku idin mbusak pesen.",
+ "no_delete_perm": "Tulung aku kei izin mbusak pesen.",
"purge_success": "Kasil mbusak {del_total} pesen..",
"user_not_found": "Aku ora bisa nemokake panganggo kuwi.",
"invalid_id_uname": "β οΈ panganggo/jeneng panganggo ora sah",
"kick_self_err": "Aku ora bisa nyepak awakku dhewe, aku bisa lunga yen sampeyan pengin.",
"ban_self_err": "Aku ora bisa nglarang aku, aku bisa lunga yen sampeyan pengin.",
"report_self_err": "Kenging menapa panjenengan lapor piyambak?",
- "demote_self_err": "Aku ora bisa mudhun mudhun.",
+ "demote_self_err": "Aku ora bisa mudhun dhewe.",
"warn_self_err": "Aku ora bisa ngelekake awakku dhewe.",
- "mute_self_err": "Aku ora bisa bisu.",
+ "mute_self_err": "Aku ora bisa bisu awakku dhewe.",
"kick_sudo_err": "Wah, kowe arep nyepak juraganku?",
"ban_sudo_err": "Wah, sampeyan pengin nyoba nglarang pemilikku?",
"demote_sudo_err": "Wah, sampeyan pengin nyoba nurunake pemilikku?",
@@ -51,7 +51,7 @@
"normal_promote": "Dipromosikan {umention}!",
"pin_success": "**Semat [iki]({link}) pesen.**",
"unpin_success": "**Pesen [iki] ({pranala}) ora disemat.**",
- "pin_no_perm": "Tulung wenehi pin idin kanggo nggunakake printah iki!.",
+ "pin_no_perm": "Tulung wenehi pin izin kanggo nggunakake printah iki!.",
"report_msg": "Kacarita {user_mention} menyang admin!",
"reported_is_admin": "Apa sampeyan ngerti yen pangguna sing sampeyan bales iku admin?",
"user_no_warn": "Panganggo {mention} ora ana bebaya.",
diff --git a/locales/id-JW/afk.json b/locales/id-JW/afk.json
new file mode 100644
index 00000000..0f37044a
--- /dev/null
+++ b/locales/id-JW/afk.json
@@ -0,0 +1,13 @@
+{
+ "no_channel": "Fitur iki ora didhukung kanggo channel.",
+ "on_afk_msg_no_r": "**{usr}** [{id}] wis online maneh lan ora ana ing {tm}\n\n",
+ "on_afk_msg_with_r": "**{usr}** [{id}] wis online maneh lan ora ana {tm}\n\n**Alesan:** `{reas}`\n\n",
+ "is_afk_msg_no_r": "**{usr}** [{id}] iku AFK wiwit {tm} kepungkur.\n\n",
+ "is_afk_msg_with_r": "**{usr}** [{id}] iku AFK wiwit {tm} kepungkur.\n\n**Alesan:** {reas}\n\n" ,
+ "is_online": "**{usr}** [{id}] wis online maneh",
+ "now_afk": "{usr} [{id}] 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} [{id}] iku AFK!."
+}
\ No newline at end of file
diff --git a/locales/id-JW/chatbot_ai.json b/locales/id-JW/chatbot_ai.json
index 1e2c1b1a..e674a2e2 100644
--- a/locales/id-JW/chatbot_ai.json
+++ b/locales/id-JW/chatbot_ai.json
@@ -1,5 +1,5 @@
{
- "no_question": "Tulung gunakake printah /{cmd} [pitakon] kanggo takon.",
- "find_answers_str": "Ngenteni sedhela goleki jawabanmu..",
+ "no_question": "Tulung gunakake printah /{cmd} [pitakon] kanggo takon nganggo fitur OpenAI.",
+ "find_answers_str": "Lagi goleki jawaban paling apik kanggo sampeyan..",
"answers_too_long": "Pitakonan kanggo jawaban sampeyan wis ngluwihi wates teks TG, priksa pranala iki kanggo ndeleng.\n\n{answerlink}"
}
\ No newline at end of file
diff --git a/locales/id-JW/dev.json b/locales/id-JW/dev.json
new file mode 100644
index 00000000..490736f9
--- /dev/null
+++ b/locales/id-JW/dev.json
@@ -0,0 +1,11 @@
+{
+ "already_up": "Wis up-to-date!",
+ "up_and_rest": "Dianyari nganggo branch standar, diwiwiti maneh saiki.",
+ "cl_btn": "β Tutup",
+ "no_eval": "__Ora ana pesen eval!__",
+ "run_eval": "Ngolah pyrogram eval..",
+ "run_exec": "Ngolah pyrogram exec..",
+ "no_cmd": "Ora ana prentah kanggo nglakokakΓ©.",
+ "success": "Sukses",
+ "no_reply": "Ora Wangsulan"
+}
\ No newline at end of file
diff --git a/locales/id-JW/genss.json b/locales/id-JW/genss.json
new file mode 100644
index 00000000..85155ab0
--- /dev/null
+++ b/locales/id-JW/genss.json
@@ -0,0 +1,13 @@
+{
+ "wait_msg": "Wenehi wektu kanggo ngolah panjalukmu!! π΄",
+ "wait_dl": "Lagi diproses, mangga ngenteni..",
+ "dl_progress": "Nyoba ngundhuh, mangga ngenteni..",
+ "up_progress": "Nyoba ngunggah...",
+ "success_dl_msg": "Berkas wis diundhuh menyang {path}.",
+ "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} ({id})\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`)"
+}
\ No newline at end of file
diff --git a/locales/id-JW/mediainfo.json b/locales/id-JW/mediainfo.json
index 447eefb0..00372a45 100644
--- a/locales/id-JW/mediainfo.json
+++ b/locales/id-JW/mediainfo.json
@@ -1,11 +1,11 @@
{
"processing_text": "`Pengolahan, wektu total adhedhasar ukuran berkas panjenengan...`",
- "wait_msg": "`Mohon tunggu sejenak...`",
+ "wait_msg": "`Tulung enteni sedhela...`",
"err_link": "Kayak'e pranala sing dikirim ora valid, priksa link langsung lan bisa diundhuh.",
"media_invalid": "Mangga mbales media sing bener.",
- "dl_limit_exceeded": "Nuwun sewu, download diwatesi 2GB kanggo nyuda banjir. Sampeyan bisa ngowahi file dadi link.",
+ "dl_limit_exceeded": "Nuwun sewu, download diwatesi 2GB kanggo nyuda flood. Sampeyan bisa ngowahi file dadi link.",
"dl_args_text": "Nyoba ngundhuh..",
"mediainfo_help": "Gunakake printah /{cmd} [link], utawa bales media telegram nganggo /{cmd}.",
- "capt_media": "βΉοΈ Hasil mediainfo anda..\n\n**Panjalukan Oleh:** {ment}",
+ "capt_media": "βΉοΈ Hasil mediainfo sampeyan..\n\n**Panjalukan Saka:** {ment}",
"viweb": "π¬ Bukak Web"
}
\ No newline at end of file
diff --git a/locales/id-JW/nightmodev2.json b/locales/id-JW/nightmodev2.json
new file mode 100644
index 00000000..045218a7
--- /dev/null
+++ b/locales/id-JW/nightmodev2.json
@@ -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}"
+}
\ No newline at end of file
diff --git a/locales/id-JW/start_help.json b/locales/id-JW/start_help.json
new file mode 100644
index 00000000..afc95879
--- /dev/null
+++ b/locales/id-JW/start_help.json
@@ -0,0 +1,11 @@
+{
+ "newgroup_log": "#NewGroup\nGroup = {jdl}({id})\nJumlah Anggota = {c}",
+ "newuser_log": "#NewUser\nID - {id}\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."
+}
\ No newline at end of file
diff --git a/locales/id-JW/stickers.json b/locales/id-JW/stickers.json
index 9936309a..19e38a7e 100644
--- a/locales/id-JW/stickers.json
+++ b/locales/id-JW/stickers.json
@@ -14,6 +14,6 @@
"please_start_msg": "Koyone sampeyan ora tau sesambungan karo aku ing obrolan pribadi, sampeyan kudu nglakoni dhisik..",
"click_me": "Klik Aku",
"pack_full": "Paket Stiker sampeyan kebak yen paket sampeyan ora ana ing tipe v1 /kang 1, yen ora ana ing Tipe v2 /kang 2 lan sapiturute.",
- "viewpack": "π Deleng Paket Sampeyan",
+ "viewpack": "π Deleng Paket",
"kang_success": "Stiker kasil dicolong!\nEmoji: {emot}"
}
\ No newline at end of file
diff --git a/locales/id-JW/web_scraper.json b/locales/id-JW/web_scraper.json
index 9e26dfee..99dd9162 100644
--- a/locales/id-JW/web_scraper.json
+++ b/locales/id-JW/web_scraper.json
@@ -1 +1,18 @@
-{}
\ No newline at end of file
+{
+ "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": "Asil scrape saka {link}:\n\n{kl}",
+ "header_with_query": "Asil Nggoleki #{web} Kanggo: {kueri}\n\n",
+ "header_no_query": "#{web} Paling anyar:\nπ Gunakake /{cmd} [judhul] kanggo miwiti nggoleki kanthi judhul.\n\n",
+ "invalid_cmd_scrape": "Gunakake prentah /{cmd} [pranala] kanggo ngunduh pranala kethokan",
+ "unsupport_dl_btn": "Sawetara asil ora bakal katon ing tombol ekstrak amarga pranala ora didhukung."
+}
\ No newline at end of file
diff --git a/locales/id-JW/ytdl_plugins.json b/locales/id-JW/ytdl_plugins.json
new file mode 100644
index 00000000..4170b220
--- /dev/null
+++ b/locales/id-JW/ytdl_plugins.json
@@ -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β― Duration: {dur}\nβ― Ndeleng: {vi}\nβ― Uploader:< /b> {cname}\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"
+}
\ No newline at end of file
diff --git a/misskaty/__main__.py b/misskaty/__main__.py
index 9b89080c..fdad6cf0 100644
--- a/misskaty/__main__.py
+++ b/misskaty/__main__.py
@@ -7,17 +7,14 @@
"""
import asyncio
import importlib
-import re
import os
import pickle
import traceback
from logging import getLogger
-from pyrogram import __version__, filters, idle
+from pyrogram import __version__, idle
from pyrogram.raw.all import layer
-from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
-from database.users_chats_db import db
from misskaty import (
BOT_NAME,
BOT_USERNAME,
@@ -26,12 +23,9 @@ from misskaty import (
app,
scheduler
)
-from misskaty.core.message_utils import *
-from misskaty.core.decorator.ratelimiter import ratelimiter
-from misskaty.helper import bot_sys_stats, paginate_modules
from misskaty.plugins import ALL_MODULES
-from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, SUDO
-from utils import auto_clean, temp
+from misskaty.vars import SUDO
+from utils import auto_clean
LOGGER = getLogger(__name__)
loop = asyncio.get_event_loop()
@@ -80,293 +74,6 @@ async def start_bot():
asyncio.create_task(auto_clean())
await idle()
-
-home_keyboard_pm = InlineKeyboardMarkup(
- [
- [
- InlineKeyboardButton(text="Commands β", callback_data="bot_commands"),
- InlineKeyboardButton(
- text="Source Code π ",
- url="https://github.com/yasirarism/MissKatyPyro",
- ),
- ],
- [
- InlineKeyboardButton(
- text="System Stats π₯",
- callback_data="stats_callback",
- ),
- InlineKeyboardButton(text="Dev π¨", url="https://t.me/YasirArisM"),
- ],
- [
- InlineKeyboardButton(
- text="Add Me To Your Group π",
- url=f"http://t.me/{BOT_USERNAME}?startgroup=new",
- )
- ],
- ]
-)
-
-home_text_pm = f"Hey there! My name is {BOT_NAME}. I have many useful features for you, feel free to add me to your group.\n\nIf you want give coffee to my owner you can send /donate command for more info."
-
-keyboard = InlineKeyboardMarkup(
- [
- [
- InlineKeyboardButton(text="Help β", url=f"t.me/{BOT_USERNAME}?start=help"),
- InlineKeyboardButton(
- text="Source Code οΏ½",
- 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}({message.chat.id})\nMembers Count = {total}\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 /setlang 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 - {message.from_user.id}\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}({message.chat.id})\nMembers Count = {total}\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 - {message.from_user.id}\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 /setlang command, but it's in beta stage.
-You can choose an option below, by clicking a button.
-
-If you want give coffee to my owner you can send /donate command for more info.
-""".format(
- first_name=name,
- bot_name="MissKaty",
- ),
- keyboard,
- )
-
-
-@app.on_callback_query(filters.regex(r"help_(.*?)"))
-@ratelimiter
-async def help_button(client, query):
- home_match = re.match(r"help_home\((.+?)\)", query.data)
- mod_match = re.match(r"help_module\((.+?)\)", query.data)
- prev_match = re.match(r"help_prev\((.+?)\)", query.data)
- next_match = re.match(r"help_next\((.+?)\)", query.data)
- back_match = re.match(r"help_back", query.data)
- create_match = re.match(r"help_create", query.data)
- top_text = f"""
-Hello {query.from_user.first_name}, My name is MissKaty.
-I'm a bot with some usefule features.
-You can choose an option below, by clicking a button below.
-
-General command are:
- - /start: Start the bot
- - /help: Give this message
- - /setlang: Change bot language [BETA]
- """
- if mod_match:
- module = mod_match[1].replace(" ", "_")
- text = f"Here is the help for **{HELPABLE[module].__MODULE__}**:\n{HELPABLE[module].__HELP__}"
-
- await editPesan(
- query.message,
- text=text,
- reply_markup=InlineKeyboardMarkup(
- [[InlineKeyboardButton("back", callback_data="help_back")]]
- ),
- disable_web_page_preview=True,
- )
- elif home_match:
- await app.send_message(
- query.from_user.id,
- text=home_text_pm,
- reply_markup=home_keyboard_pm,
- )
- await hapusPesan(query.message)
- elif prev_match:
- curr_page = int(prev_match[1])
- await editPesan(
- query.message,
- text=top_text,
- reply_markup=InlineKeyboardMarkup(
- paginate_modules(curr_page - 1, HELPABLE, "help")
- ),
- disable_web_page_preview=True,
- )
-
- elif next_match:
- next_page = int(next_match[1])
- await editPesan(
- query.message,
- text=top_text,
- reply_markup=InlineKeyboardMarkup(
- paginate_modules(next_page + 1, HELPABLE, "help")
- ),
- disable_web_page_preview=True,
- )
-
- elif back_match:
- await editPesan(
- query.message,
- text=top_text,
- reply_markup=InlineKeyboardMarkup(paginate_modules(0, HELPABLE, "help")),
- disable_web_page_preview=True,
- )
-
- elif create_match:
- text, keyboard = await help_parser(query)
- await editPesan(
- query.message,
- text=text,
- reply_markup=keyboard,
- disable_web_page_preview=True,
- )
-
- return await client.answer_callback_query(query.id)
-
-
-
-
if __name__ == "__main__":
try:
loop.run_until_complete(start_bot())
diff --git a/misskaty/core/decorator/permissions.py b/misskaty/core/decorator/permissions.py
index 6af18b93..cdf099f7 100644
--- a/misskaty/core/decorator/permissions.py
+++ b/misskaty/core/decorator/permissions.py
@@ -39,6 +39,47 @@ async def member_permissions(chat_id: int, user_id: int):
perms.append("can_manage_video_chats")
return perms
+async def check_perms(
+ message: Union[CallbackQuery, Message],
+ permissions: Optional[Union[list, str]],
+ complain_missing_perms: bool,
+ strings,
+) -> bool:
+ if isinstance(message, CallbackQuery):
+ sender = partial(message.answer, show_alert=True)
+ chat = message.message.chat
+ else:
+ sender = message.reply_text
+ chat = message.chat
+ # TODO: Cache all admin permissions in db.
+ user = await chat.get_member(message.from_user.id)
+ if user.status == enums.ChatMemberStatus.OWNER:
+ return True
+
+ # No permissions specified, accept being an admin.
+ if not permissions and user.status == enums.ChatMemberStatus.ADMINISTRATOR:
+ return True
+ if user.status != enums.ChatMemberStatus.ADMINISTRATOR:
+ if complain_missing_perms:
+ await sender(strings("no_admin_error"))
+ return False
+
+ if isinstance(permissions, str):
+ permissions = [permissions]
+
+ missing_perms = [
+ permission
+ for permission in permissions
+ if not getattr(user.privileges, permission)
+ ]
+
+ if not missing_perms:
+ return True
+ if complain_missing_perms:
+ await sender(
+ strings("no_permission_error").format(permissions=", ".join(missing_perms))
+ )
+ return False
async def check_perms(
message: Union[CallbackQuery, Message],
@@ -148,7 +189,6 @@ def adminsOnly(permission):
return subFunc
-
def require_admin(
permissions: Union[list, str] = None,
allow_in_private: bool = False,
diff --git a/misskaty/helper/localization.py b/misskaty/helper/localization.py
index 30354544..6076e24b 100644
--- a/misskaty/helper/localization.py
+++ b/misskaty/helper/localization.py
@@ -79,7 +79,7 @@ async def get_lang(message) -> str:
else:
raise TypeError(f"Update type '{message.__name__}' is not supported.")
- lang = await get_db_lang(chat.id, chat.type)
+ lang = await get_db_lang(chat.id)
if chat.type == ChatType.PRIVATE:
lang = lang or message.from_user.language_code or default_language
diff --git a/misskaty/plugins/admin.py b/misskaty/plugins/admin.py
index 8dcc5896..54f27b6d 100644
--- a/misskaty/plugins/admin.py
+++ b/misskaty/plugins/admin.py
@@ -365,32 +365,28 @@ async def promoteFunc(client, message, strings):
return await message.reply_text(strings("no_promote_perm"))
if message.command[0][0] == "f":
await message.chat.promote_member(
- user_id,
- ChatPrivileges(
- can_change_info=bot.can_change_info,
- can_invite_users=bot.can_invite_users,
- can_delete_messages=bot.can_delete_messages,
- can_restrict_members=bot.can_restrict_members,
- can_pin_messages=bot.can_pin_messages,
- can_promote_members=bot.can_promote_members,
- can_manage_chat=bot.can_manage_chat,
- can_manage_voice_chats=bot.can_manage_voice_chats,
- ),
+ user_id=user_id,
+ can_change_info=bot.privileges.can_change_info,
+ can_invite_users=bot.privileges.can_invite_users,
+ can_delete_messages=bot.privileges.can_delete_messages,
+ can_restrict_members=bot.privileges.can_restrict_members,
+ can_pin_messages=bot.privileges.can_pin_messages,
+ can_promote_members=bot.privileges.can_promote_members,
+ can_manage_chat=bot.privileges.can_manage_chat,
+ can_manage_video_chats=bot.privileges.can_manage_video_chats,
)
return await message.reply_text(strings("full_promote").format(umention=umention))
await message.chat.promote_member(
- user_id,
- ChatPrivileges(
- can_change_info=False,
- can_invite_users=bot.can_invite_users,
- can_delete_messages=bot.can_delete_messages,
- can_restrict_members=False,
- can_pin_messages=False,
- can_promote_members=False,
- can_manage_chat=bot.can_manage_chat,
- can_manage_voice_chats=bot.can_manage_voice_chats,
- ),
+ user_id=user_id,
+ can_change_info=False,
+ can_invite_users=bot.privileges.can_invite_users,
+ can_delete_messages=bot.privileges.can_delete_messages,
+ can_restrict_members=bot.privileges.can_restrict_members,
+ can_pin_messages=bot.privileges.can_pin_messages,
+ can_promote_members=False,
+ can_manage_chat=bot.privileges.can_manage_chat,
+ can_manage_video_chats=bot.privileges.can_manage_video_chats,
)
await message.reply_text(strings("normal_promote").format(umention=umention))
@@ -410,7 +406,17 @@ async def demote(client, message, strings):
return await message.reply_text(strings("demote_self_err"))
if user_id in SUDO:
return await message.reply_text(strings("demote_sudo_err"))
- await message.chat.promote_member(user_id=user_id)
+ await message.chat.promote_member(
+ user_id=user_id,
+ can_change_info=False,
+ can_invite_users=False,
+ can_delete_messages=False,
+ can_restrict_members=False,
+ can_pin_messages=False,
+ can_promote_members=False,
+ can_manage_chat=False,
+ can_manage_video_chats=False,
+ )
umention = (await app.get_users(user_id)).mention
await message.reply_text(f"Demoted! {umention}")
@@ -507,8 +513,8 @@ async def unmute(_, message, strings):
if not user_id:
return await message.reply_text(strings("user_not_found"))
await message.chat.unban_member(user_id)
- (await app.get_users(user_id)).mention
- await message.reply_text(strings("unmute_msg"))
+ umention = (await app.get_users(user_id)).mention
+ await message.reply_text(strings("unmute_msg").format(umention=umention))
@app.on_message(filters.command(["warn", "dwarn"], COMMAND_HANDLER) & filters.group)
diff --git a/misskaty/plugins/afk.py b/misskaty/plugins/afk.py
index dafb5fe2..0babe409 100644
--- a/misskaty/plugins/afk.py
+++ b/misskaty/plugins/afk.py
@@ -10,8 +10,9 @@
# Modified plugin by me from https://github.com/TeamYukki/YukkiAFKBot to make compatible with pyrogram v2
import time
+import re
-from pyrogram import filters
+from pyrogram import filters, enums
from database.afk_db import add_afk, cleanmode_off, cleanmode_on, is_afk, remove_afk
from misskaty import app
@@ -20,6 +21,7 @@ from misskaty.core.decorator.permissions import adminsOnly
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import kirimPesan
from misskaty.helper import get_readable_time2
+from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
from utils import put_cleanmode
@@ -34,9 +36,10 @@ Just type something in group to remove AFK Status."""
@capture_err
@app.on_message(filters.command(["afk"], COMMAND_HANDLER))
@ratelimiter
-async def active_afk(_, message):
+@use_chat_lang()
+async def active_afk(_, message, strings):
if message.sender_chat:
- return await kirimPesan(message, "This feature not supported for channel.")
+ return await kirimPesan(message, strings("no_channel"))
user_id = message.from_user.id
verifier, reasondb = await is_afk(user_id)
if verifier:
@@ -51,39 +54,39 @@ async def active_afk(_, message):
send = (
await message.reply_animation(
data,
- caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}",
+ caption=strings("on_afk_msg_no_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago),
)
if str(reasonafk) == "None"
else await message.reply_animation(
data,
- caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}\n\nReason: `{reasonafk}`",
+ caption=strings("on_afk_msg_with_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago, reas=reasonafk),
)
)
elif afktype == "photo":
send = (
await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
- caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}",
+ caption=strings("on_afk_msg_no_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago),
)
if str(reasonafk) == "None"
else await message.reply_photo(
photo=f"downloads/{user_id}.jpg",
- caption=f"**{message.from_user.first_name}** is back online and was away for {seenago}\n\nReason: `{reasonafk}`",
+ caption=strings("on_afk_msg_with_r").format(usr=message.from_user.first_name, tm=seenago, reas=reasonafk),
)
)
elif afktype == "text":
send = await message.reply_text(
- f"**{message.from_user.first_name}** is back online and was away for {seenago}",
+ caption=strings("on_afk_msg_no_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago),
disable_web_page_preview=True,
)
elif afktype == "text_reason":
send = await message.reply_text(
- f"**{message.from_user.first_name}** is back online and was away for {seenago}\n\nReason: `{reasonafk}`",
+ caption=strings("on_afk_msg_with_r").format(usr=message.from_user.mention, id=message.from_user.id, tm=seenago, reas=reasonafk),
disable_web_page_preview=True,
)
except Exception:
send = await message.reply_text(
- f"**{message.from_user.first_name}** is back online",
+ strings("is_online").format(usr=message.from_user.first_name),
disable_web_page_preview=True,
)
await put_cleanmode(message.chat.id, send.id)
@@ -179,27 +182,242 @@ async def active_afk(_, message):
}
await add_afk(user_id, details)
- send = await kirimPesan(message, f"{message.from_user.mention} [{message.from_user.id}] is now AFK!.")
+ send = await kirimPesan(message, strings("now_afk").format(usr=message.from_user.mention, id=message.from_user.id))
await put_cleanmode(message.chat.id, send.id)
@app.on_message(filters.command("afkdel", COMMAND_HANDLER) & filters.group)
@ratelimiter
@adminsOnly("can_change_info")
-async def afk_state(_, message):
+@use_chat_lang()
+async def afk_state(_, message, strings):
if not message.from_user:
return
- usage = "**Usage:**\n/afkdel [ENABLE|DISABLE] to enable or disable auto delete message."
if len(message.command) == 1:
- return await kirimPesan(message, usage)
+ return await kirimPesan(message, strings("afkdel_help").format(cmd=message.command[0]))
chat_id = message.chat.id
state = message.text.split(None, 1)[1].strip()
state = state.lower()
if state == "enable":
await cleanmode_on(chat_id)
- await kirimPesan(message, "Enabled auto delete AFK message in this chat.")
+ await kirimPesan(message, strings("afkdel_enable"))
elif state == "disable":
await cleanmode_off(chat_id)
- await kirimPesan(message, "Disabled auto delete AFK message.")
+ await kirimPesan(message, strings("afkdel_disable"))
else:
- await kirimPesan(message, usage)
+ await kirimPesan(message, strings("afkdel_help").format(cmd=message.command[0]))
+
+
+# Detect user that AFK based on Yukki Repo
+@app.on_message(
+ filters.group & ~filters.bot & ~filters.via_bot,
+ group=1,
+)
+@use_chat_lang()
+async def chat_watcher_func(client, message, strings):
+ if message.sender_chat:
+ return
+ userid = message.from_user.id
+ user_name = message.from_user.mention
+ if message.entities:
+ possible = ["/afk", f"/afk@{client.me.username}", "!afk"]
+ message_text = message.text or message.caption
+ for entity in message.entities:
+ if entity.type == enums.MessageEntityType.BOT_COMMAND:
+ if (message_text[0 : 0 + entity.length]).lower() in possible:
+ return
+
+ msg = ""
+ replied_user_id = 0
+
+ # Self AFK
+ verifier, reasondb = await is_afk(userid)
+ if verifier:
+ await remove_afk(userid)
+ try:
+ afktype = reasondb["type"]
+ timeafk = reasondb["time"]
+ data = reasondb["data"]
+ reasonafk = reasondb["reason"]
+ seenago = get_readable_time2((int(time.time() - timeafk)))
+ if afktype == "text":
+ msg += strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago)
+ if afktype == "text_reason":
+ msg += strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk)
+ if afktype == "animation":
+ if str(reasonafk) == "None":
+ send = await message.reply_animation(
+ data,
+ caption=strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago),
+ )
+ else:
+ send = await message.reply_animation(
+ data,
+ caption=strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk),
+ )
+ if afktype == "photo":
+ if str(reasonafk) == "None":
+ send = await message.reply_photo(
+ photo=f"downloads/{userid}.jpg",
+ caption=strings("on_afk_msg_no_r").format(usr=user_name, id=userid, tm=seenago),
+ )
+ else:
+ send = await message.reply_photo(
+ photo=f"downloads/{userid}.jpg",
+ caption=strings("on_afk_msg_with_r").format(usr=user_name, id=userid, tm=seenago, reas=reasonafk),
+ )
+ except:
+ msg += strings("is_online").format(usr=user_name, id=userid)
+
+ # Replied to a User which is AFK
+ if message.reply_to_message:
+ try:
+ replied_first_name = message.reply_to_message.from_user.mention
+ replied_user_id = message.reply_to_message.from_user.id
+ verifier, reasondb = await is_afk(replied_user_id)
+ if verifier:
+ try:
+ afktype = reasondb["type"]
+ timeafk = reasondb["time"]
+ data = reasondb["data"]
+ reasonafk = reasondb["reason"]
+ seenago = get_readable_time2((int(time.time() - timeafk)))
+ if afktype == "text":
+ msg += strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago)
+ if afktype == "text_reason":
+ msg += strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk)
+ if afktype == "animation":
+ if str(reasonafk) == "None":
+ send = await message.reply_animation(
+ data,
+ caption=strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago),
+ )
+ else:
+ send = await message.reply_animation(
+ data,
+ caption=strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk),
+ )
+ if afktype == "photo":
+ if str(reasonafk) == "None":
+ send = await message.reply_photo(
+ photo=f"downloads/{replied_user_id}.jpg",
+ caption=strings("is_afk_msg_no_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago),
+ )
+ else:
+ send = await message.reply_photo(
+ photo=f"downloads/{replied_user_id}.jpg",
+ caption=strings("is_afk_msg_with_r").format(usr=replied_first_name, id=replied_user_id, tm=seenago, reas=reasonafk),
+ )
+ except Exception:
+ msg += strings("is_afk").format(usr=replied_first_name, id=replied_user_id)
+ except:
+ pass
+
+ # If username or mentioned user is AFK
+ if message.entities:
+ entity = message.entities
+ j = 0
+ for x in range(len(entity)):
+ if (entity[j].type) == enums.MessageEntityType.MENTION:
+ found = re.findall("@([_0-9a-zA-Z]+)", message.text)
+ try:
+ get_user = found[j]
+ user = await app.get_users(get_user)
+ if user.id == replied_user_id:
+ j += 1
+ continue
+ except:
+ j += 1
+ continue
+ verifier, reasondb = await is_afk(user.id)
+ if verifier:
+ try:
+ afktype = reasondb["type"]
+ timeafk = reasondb["time"]
+ data = reasondb["data"]
+ reasonafk = reasondb["reason"]
+ seenago = get_readable_time2((int(time.time() - timeafk)))
+ if afktype == "text":
+ msg += strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago)
+ if afktype == "text_reason":
+ msg += strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk)
+ if afktype == "animation":
+ if str(reasonafk) == "None":
+ send = await message.reply_animation(
+ data,
+ caption=strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago),
+ )
+ else:
+ send = await message.reply_animation(
+ data,
+ caption=strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk),
+ )
+ if afktype == "photo":
+ if str(reasonafk) == "None":
+ send = await message.reply_photo(
+ photo=f"downloads/{user.id}.jpg",
+ caption=strings("is_afk_msg_no_r").format(usr=user.first_name[:25], id=user.id, tm=seenago),
+ )
+ else:
+ send = await message.reply_photo(
+ photo=f"downloads/{user.id}.jpg",
+ caption=strings("is_afk_msg_with_r").format(usr=user.first_name[:25], id=user.id, tm=seenago, reas=reasonafk),
+ )
+ except:
+ msg += strings("is_afk").format(usr=user.first_name[:25], id=user.id)
+ elif (entity[j].type) == enums.MessageEntityType.TEXT_MENTION:
+ try:
+ user_id = entity[j].user.id
+ if user_id == replied_user_id:
+ j += 1
+ continue
+ first_name = entity[j].user.first_name
+ except:
+ j += 1
+ continue
+ verifier, reasondb = await is_afk(user_id)
+ if verifier:
+ try:
+ afktype = reasondb["type"]
+ timeafk = reasondb["time"]
+ data = reasondb["data"]
+ reasonafk = reasondb["reason"]
+ seenago = get_readable_time2((int(time.time() - timeafk)))
+ if afktype == "text":
+ msg += strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago)
+ if afktype == "text_reason":
+ msg += strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk)
+ if afktype == "animation":
+ if str(reasonafk) == "None":
+ send = await message.reply_animation(
+ data,
+ caption=strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago),
+ )
+ else:
+ send = await message.reply_animation(
+ data,
+ caption=strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk),
+ )
+ if afktype == "photo":
+ if str(reasonafk) == "None":
+ send = await message.reply_photo(
+ photo=f"downloads/{user_id}.jpg",
+ caption=strings("is_afk_msg_no_r").format(usr=first_name[:25], id=user_id, tm=seenago),
+ )
+ else:
+ send = await message.reply_photo(
+ photo=f"downloads/{user_id}.jpg",
+ caption=strings("is_afk_msg_with_r").format(usr=first_name[:25], id=user_id, tm=seenago, reas=reasonafk),
+ )
+ except:
+ msg += strings("is_afk").format(usr=first_name[:25], id=user_id)
+ j += 1
+ if msg != "":
+ try:
+ send = await message.reply_text(msg, disable_web_page_preview=True)
+ except:
+ pass
+ try:
+ await put_cleanmode(message.chat.id, send.id)
+ except:
+ pass
\ No newline at end of file
diff --git a/misskaty/plugins/bypass.py b/misskaty/plugins/bypass.py
index d1c76b1e..cf35a2aa 100644
--- a/misskaty/plugins/bypass.py
+++ b/misskaty/plugins/bypass.py
@@ -37,6 +37,7 @@ Supported Link:
Credit: PyBypass
"""
+# Stopped development for this plugin since always changed time by time.
async def pling_bypass(url):
try:
diff --git a/misskaty/plugins/detect_afk.py b/misskaty/plugins/detect_afk.py
deleted file mode 100644
index ce93a984..00000000
--- a/misskaty/plugins/detect_afk.py
+++ /dev/null
@@ -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
diff --git a/misskaty/plugins/dev.py b/misskaty/plugins/dev.py
index 7eeedd65..66f11a9c 100644
--- a/misskaty/plugins/dev.py
+++ b/misskaty/plugins/dev.py
@@ -17,6 +17,7 @@ from pyrogram import enums, filters
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup
from misskaty import app, user, botStartTime, BOT_NAME
+from misskaty.helper.localization import use_chat_lang
from misskaty.helper.human_read import get_readable_file_size, get_readable_time
from misskaty.core.message_utils import editPesan, hapusPesan, kirimPesan
from misskaty.vars import COMMAND_HANDLER, SUDO
@@ -40,7 +41,8 @@ async def edit_or_reply(msg, **kwargs):
@app.on_message(filters.command(["logs"], COMMAND_HANDLER) & filters.user(SUDO))
-async def log_file(bot, message):
+@use_chat_lang()
+async def log_file(bot, message, strings):
"""Send log file"""
try:
await message.reply_document(
@@ -50,7 +52,7 @@ async def log_file(bot, message):
[
[
InlineKeyboardButton(
- "β Close",
+ strings("cl_btn"),
f"close#{message.from_user.id}",
)
]
@@ -105,11 +107,12 @@ RAM Usage: `{virtual_memory().percent}%`
@app.on_message(filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO))
@app.on_edited_message(filters.command(["shell", "sh"], COMMAND_HANDLER) & filters.user(SUDO))
@user.on_message(filters.command(["shell", "sh"], ".") & filters.me)
-async def shell(_, m):
+@use_chat_lang()
+async def shell(_, m, strings):
cmd = m.text.split(" ", 1)
if len(m.command) == 1:
- return await edit_or_reply(m, text="No command to execute was given.")
- msg = await editPesan(m, "Processing exec pyrogram...") if m.from_user.is_self else await kirimPesan(m, "Processing exec pyrogram...")
+ return await edit_or_reply(m, text=strings("no_cmd"))
+ msg = await editPesan(m, strings("run_exec")) if m.from_user.is_self else await kirimPesan(m, strings("run_exec"))
shell = (await shell_exec(cmd[1]))[0]
if len(shell) > 3000:
with open("shell_output.txt", "w") as file:
@@ -118,7 +121,7 @@ async def shell(_, m):
await m.reply_document(
document=doc,
file_name=doc.name,
- reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="β Close", callback_data=f"close#{m.from_user.id}")]]),
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
await msg.delete()
try:
@@ -130,22 +133,23 @@ async def shell(_, m):
m,
text=shell,
parse_mode=enums.ParseMode.HTML,
- reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="β Close", callback_data=f"close#{m.from_user.id}")]]),
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
if not m.from_user.is_self:
await msg.delete()
else:
- await m.reply("No Reply")
+ await m.reply(strings("no_reply"))
@app.on_message((filters.command(["ev", "run"], COMMAND_HANDLER) | filters.regex(r"app.run\(\)$")) & filters.user(SUDO))
@app.on_edited_message((filters.command(["ev", "run"]) | filters.regex(r"app.run\(\)$")) & filters.user(SUDO))
@user.on_message(filters.command(["ev", "run"], ".") & filters.me)
-async def evaluation_cmd_t(_, m):
+@use_chat_lang()
+async def evaluation_cmd_t(_, m, strings):
if (m.command and len(m.command) == 1) or m.text == "app.run()":
- return await edit_or_reply(m, text="__No evaluate message!__")
+ return await edit_or_reply(m, text=strings("no_eval"))
cmd = m.text.split(" ", 1)[1] if m.command else m.text.split("\napp.run()")[0]
- status_message = await editPesan(m, "Processing eval pyrogram..") if m.from_user.is_self else await kirimPesan(m, "Processing eval pyrogram..", quote=True)
+ status_message = await editPesan(m, strings("run_eval")) if m.from_user.is_self else await kirimPesan(m, strings("run_eval"), quote=True)
old_stderr = sys.stderr
old_stdout = sys.stdout
@@ -201,7 +205,7 @@ async def evaluation_cmd_t(_, m):
elif stdout:
evaluation = stdout
else:
- evaluation = "Success"
+ evaluation = strings("success")
final_output = f"**EVAL**:\n`{cmd}`\n\n**OUTPUT**:\n`{evaluation.strip()}`\n"
@@ -213,7 +217,7 @@ async def evaluation_cmd_t(_, m):
caption=f"{cmd[1][: 4096 // 4 - 1]}",
disable_notification=True,
thumb="assets/thumb.jpg",
- reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="β Close", callback_data=f"close#{m.from_user.id}")]]),
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
os.remove("MissKatyEval.txt")
await status_message.delete()
@@ -222,7 +226,7 @@ async def evaluation_cmd_t(_, m):
m,
text=final_output,
parse_mode=enums.ParseMode.MARKDOWN,
- reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text="β Close", callback_data=f"close#{m.from_user.id}")]]),
+ reply_markup=InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("cl_btn"), callback_data=f"close#{m.from_user.id}")]]),
)
if not m.from_user.is_self:
await status_message.delete()
@@ -230,15 +234,16 @@ async def evaluation_cmd_t(_, m):
# Update and restart bot
@app.on_message(filters.command(["update"], COMMAND_HANDLER) & filters.user(SUDO))
-async def update_restart(_, message):
+@use_chat_lang()
+async def update_restart(_, message, strings):
try:
out = (await shell_exec("git pull"))[0]
if "Already up to date." in str(out):
- return await message.reply_text("Its already up-to date!")
+ return await message.reply_text(strings("already_up"))
await message.reply_text(f"{out}")
except Exception as e:
return await message.reply_text(str(e))
- msg = await message.reply_text("Updated with default branch, restarting now.")
+ msg = await message.reply_text(strings("up_and_rest"))
with open("restart.pickle", "wb") as status:
pickle.dump([message.chat.id, msg.id], status)
os.execvp(sys.executable, [sys.executable, "-m", "misskaty"])
diff --git a/misskaty/plugins/fun.py b/misskaty/plugins/fun.py
index d4c74e95..7ca7ff24 100644
--- a/misskaty/plugins/fun.py
+++ b/misskaty/plugins/fun.py
@@ -159,7 +159,6 @@ async def memify(client, message):
else:
await message.reply("Gunakan command /mmf dengan reply ke sticker, pisahkan dengan ; untuk membuat posisi text dibawah.")
-
@app.on_message(filters.command(["dice"], COMMAND_HANDLER))
@use_chat_lang()
async def dice(c, m, strings):
diff --git a/misskaty/plugins/genss.py b/misskaty/plugins/genss.py
index 2b447424..644d77b0 100644
--- a/misskaty/plugins/genss.py
+++ b/misskaty/plugins/genss.py
@@ -15,10 +15,11 @@ from pyrogram import enums, filters
from pyrogram.errors import FloodWait
from pyrogram.types import InlineKeyboardMarkup
-from misskaty import BOT_USERNAME, app
+from misskaty import app
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.core.message_utils import *
from misskaty.helper import gen_ik_buttons, get_duration, is_url, progress_for_pyrogram, screenshot_flink, take_ss
+from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER
LOGGER = getLogger(__name__)
@@ -32,40 +33,41 @@ __HELP__ = """"
@app.on_message(filters.command(["genss"], COMMAND_HANDLER))
@ratelimiter
-async def genss(client, m):
+@use_chat_lang()
+async def genss(c, m, strings):
if not m.from_user:
return
replied = m.reply_to_message
if len(m.command) == 2 and is_url(m.command[1]):
- snt = await kirimPesan(m, "Give me some time to process your request!! π΄", quote=True)
+ snt = await kirimPesan(m, strings("wait_msg"), quote=True)
duration = await get_duration(m.command[1])
if isinstance(duration, str):
- return await editPesan(snt, "π Sorry! I cannot open the file.")
+ return await editPesan(snt, strings("fail_open"))
btns = gen_ik_buttons()
- await editPesan(snt, f"Now choose how many result for screenshot? π₯³.\n\nTotal duration: `{datetime.timedelta(seconds=duration)}` (`{duration}s`)", reply_markup=InlineKeyboardMarkup(btns))
+ await editPesan(snt, strings("choose_no_ss").format(td=datetime.timedelta(seconds=duration), dur=duration), reply_markup=InlineKeyboardMarkup(btns))
elif replied and replied.media:
vid = [replied.video, replied.document]
media = next((v for v in vid if v is not None), None)
if media is None:
- return await kirimPesan(m, "Reply to a Telegram Video or document as video to generate screenshoot!", quote=True)
- process = await kirimPesan(m, "Processing, please wait..", quote=True)
+ return await kirimPesan(m, strings("no_reply"), quote=True)
+ process = await kirimPesan(m, strings("wait_dl"), quote=True)
if media.file_size > 2097152000:
- return await editPesan(process, "Sorry, download limited to 2GB to reduce flood. You can convert your files to link.")
+ return await editPesan(process, strings("limit_dl"))
c_time = time.time()
dl = await replied.download(
file_name="/downloads/",
progress=progress_for_pyrogram,
- progress_args=("Trying to download, please wait..", process, c_time),
+ progress_args=(strings("dl_progress"), process, c_time),
)
the_real_download_location = os.path.join("/downloads/", os.path.basename(dl))
if the_real_download_location is not None:
try:
- await editPesan(process, f"File video berhasil didownload dengan path {the_real_download_location}.")
+ await editPesan(process, strings("success_dl_msg"))
await sleep(2)
images = await take_ss(the_real_download_location)
- await editPesan(process, "Mencoba mengupload, hasil generate screenshot..")
- await client.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO)
+ await editPesan(process, strings("up_progress"))
+ await c.send_chat_action(chat_id=m.chat.id, action=enums.ChatAction.UPLOAD_PHOTO)
try:
await gather(
@@ -84,7 +86,7 @@ async def genss(client, m):
)
await kirimPesan(
m,
- f"βοΈ Uploaded [1] screenshoot.\n\n{m.from_user.first_name} ({m.from_user.id})\n#οΈβ£ #ssgen #id{m.from_user.id}\n\nSS Generate by @{BOT_USERNAME}",
+ strings("up_msg").format(namma=m.from_user.mention, id=m.from_user.id, bot_uname=c.me.username),
reply_to_message_id=m.id,
)
await process.delete()
@@ -94,14 +96,14 @@ async def genss(client, m):
except:
pass
except Exception as exc:
- await kirimPesan(m, f"Gagal generate screenshot.\n\n{exc}")
+ await kirimPesan(m, strings("err_ssgen").format(exc=exc))
try:
os.remove(images)
os.remove(the_real_download_location)
except:
pass
else:
- await kirimPesan(m, "Reply to a Telegram media to get screenshots from media..")
+ await kirimPesan(m, strings("no_reply"))
@app.on_callback_query(filters.regex(r"^scht"))
diff --git a/misskaty/plugins/karma.py b/misskaty/plugins/karma.py
index 939405fb..971d826b 100644
--- a/misskaty/plugins/karma.py
+++ b/misskaty/plugins/karma.py
@@ -27,18 +27,16 @@ Give reputation to other people in group.
karma_positive_group = 3
karma_negative_group = 4
-regex_upvote = r"^(\+|\+\+|\+1|thx|tnx|ty|thank you|thanx|thanks|pro|cool|good|makasih|π|\+\+ .+)$"
-regex_downvote = r"^(-|--|-1|π|-- .+)$"
+regex_upvote = r"^(\+|\+\+|\+1|thx|tnx|ty|tq|thank you|thanx|thanks|pro|cool|good|agree|makasih|π|\+\+ .+)$"
+regex_downvote = r"^(-|--|-1|not cool|disagree|worst|bad|π|-- .+)$"
n = "\n"
w = " "
bold = lambda x: f"**{x}:** "
bold_ul = lambda x: f"**--{x}:**-- "
-
mono = lambda x: f"`{x}`{n}"
-
def section(
title: str,
body: dict,
@@ -48,18 +46,32 @@ def section(
text = (bold_ul(title) + n) if underline else bold(title) + n
for key, value in body.items():
- text += indent * w + bold(key) + ((value[0] + n) if isinstance(value, list) else mono(value))
+ text += (
+ indent * w
+ + bold(key)
+ + ((value[0] + n) if isinstance(value, list) else mono(value))
+ )
return text
-
async def get_user_id_and_usernames(client) -> dict:
with client.storage.lock, client.storage.conn:
- users = client.storage.conn.execute('SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null').fetchall()
- return {user[0]: user[3] for user in users}
+ users = client.storage.conn.execute(
+ 'SELECT * FROM peers WHERE type in ("user", "bot") AND username NOT null'
+ ).fetchall()
+ users_ = {}
+ for user in users:
+ users_[user[0]] = user[3]
+ return users_
@app.on_message(
- filters.text & filters.group & filters.incoming & filters.reply & filters.regex(regex_upvote, re.IGNORECASE) & ~filters.via_bot & ~filters.bot,
+ filters.text
+ & filters.group
+ & filters.incoming
+ & filters.reply
+ & filters.regex(regex_upvote, re.IGNORECASE)
+ & ~filters.via_bot
+ & ~filters.bot,
group=karma_positive_group,
)
@capture_err
@@ -79,15 +91,25 @@ async def upvote(_, message):
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma + 1
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
- await message.reply_text(f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}")
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
+ await message.reply_text(
+ f"Incremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
+ )
@app.on_message(
- filters.text & filters.group & filters.incoming & filters.reply & filters.regex(regex_downvote, re.IGNORECASE) & ~filters.via_bot & ~filters.bot,
+ filters.text
+ & filters.group
+ & filters.incoming
+ & filters.reply
+ & filters.regex(regex_downvote, re.IGNORECASE)
+ & ~filters.via_bot
+ & ~filters.bot,
group=karma_negative_group,
)
@capture_err
@@ -102,22 +124,37 @@ async def downvote(_, message):
return
chat_id = message.chat.id
+ user_id = message.from_user.id
+ current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
+ if current_karma:
+ current_karma = current_karma["karma"]
+ karma = current_karma - 1
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
+ else:
+ karma = 1
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
+
user_id = message.reply_to_message.from_user.id
user_mention = message.reply_to_message.from_user.mention
current_karma = await get_karma(chat_id, await int_to_alpha(user_id))
if current_karma:
current_karma = current_karma["karma"]
karma = current_karma - 1
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
else:
karma = 1
- new_karma = {"karma": karma}
- await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
- await message.reply_text(f"Decremented Karma Of {user_mention} By 1 \nTotal Points: {karma}")
+ new_karma = {"karma": karma}
+ await update_karma(chat_id, await int_to_alpha(user_id), new_karma)
+ await message.reply_text(
+ f"Decremented Karma of {user_mention} By 1 \nTotal Points: {karma}"
+ )
@app.on_message(filters.command("karma") & filters.group)
@capture_err
-@ratelimiter
async def command_karma(_, message):
chat_id = message.chat.id
if not message.reply_to_message:
@@ -149,22 +186,25 @@ async def command_karma(_, message):
if int(user_idd) not in list(userdb.keys()):
continue
username = userdb[int(user_idd)]
- karma[f"@{username}"] = [f"**{str(karma_count)}**"]
+ karma["@" + username] = ["**" + str(karma_count) + "**"]
limit += 1
await m.edit(section(msg, karma))
else:
if not message.reply_to_message.from_user:
- return await message.reply("Anon user hash no karma.")
+ return await message.reply("Anon user has no karma.")
user_id = message.reply_to_message.from_user.id
karma = await get_karma(chat_id, await int_to_alpha(user_id))
- karma = karma["karma"] if karma else 0
- await message.reply_text(f"**Total Points**: __{karma}__")
+ if karma:
+ karma = karma["karma"]
+ await message.reply_text(f"**Total Points**: __{karma}__")
+ else:
+ karma = 0
+ await message.reply_text(f"**Total Points**: __{karma}__")
@app.on_message(filters.command("karma_toggle") & ~filters.private)
-@adminsOnly
-@ratelimiter
+@adminsOnly("can_change_info")
async def captcha_state(_, message):
usage = "**Usage:**\n/karma_toggle [ENABLE|DISABLE]"
if len(message.command) != 2:
@@ -174,9 +214,9 @@ async def captcha_state(_, message):
state = state.lower()
if state == "enable":
await karma_on(chat_id)
- await message.reply_text("Enabled karma system.")
+ await message.reply_text("Enabled Karma System for this chat.")
elif state == "disable":
await karma_off(chat_id)
- await message.reply_text("Disabled karma system.")
+ await message.reply_text("Disabled Karma System for this chat.")
else:
- await message.reply_text(usage)
+ await message.reply_text(usage)
\ No newline at end of file
diff --git a/misskaty/plugins/mediainfo.py b/misskaty/plugins/mediainfo.py
index 27525c59..d50b41d1 100644
--- a/misskaty/plugins/mediainfo.py
+++ b/misskaty/plugins/mediainfo.py
@@ -56,11 +56,11 @@ DETAILS
file_info.message_type
try:
link = await mediainfo_paste(out, "MissKaty Mediainfo")
- markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
+ markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
try:
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text)
- markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
+ markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
markup = None
with io.BytesIO(str.encode(body_text)) as out_file:
@@ -91,11 +91,11 @@ DETAILS
# link = await post_to_telegraph(False, title, body_text)
try:
link = await mediainfo_paste(out, "MissKaty Mediainfo")
- markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
+ markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
try:
link = await post_to_telegraph(False, "MissKaty MediaInfo", body_text)
- markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("vweb"), url=link)]])
+ markup = InlineKeyboardMarkup([[InlineKeyboardButton(text=strings("viweb"), url=link)]])
except:
markup = None
with io.BytesIO(str.encode(output)) as out_file:
diff --git a/misskaty/plugins/nightmodev2.py b/misskaty/plugins/nightmodev2.py
index 6c60e871..191c4698 100644
--- a/misskaty/plugins/nightmodev2.py
+++ b/misskaty/plugins/nightmodev2.py
@@ -7,10 +7,12 @@ from pyrogram import filters, __version__
from pyrogram.errors import ChannelInvalid, ChannelPrivate, ChatAdminRequired, ChatNotModified
from pyrogram.types import ChatPermissions, InlineKeyboardButton, InlineKeyboardMarkup
-from misskaty import BOT_NAME, BOT_USERNAME, app, scheduler
+from database.locale_db import get_db_lang
+from misskaty import BOT_NAME, app, scheduler
from misskaty.core.message_utils import *
from misskaty.core.decorator.ratelimiter import ratelimiter
-from misskaty.core.decorator.permissions import adminsOnly
+from misskaty.core.decorator.permissions import require_admin
+from misskaty.helper.localization import use_chat_lang, langdict
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL, TZ
__MODULE__ = "NightMode"
@@ -85,46 +87,49 @@ def extract_time(time_val: str):
async def un_mute_chat(chat_id: int, perm: ChatPermissions):
+ getlang = await get_db_lang(chat_id)
try:
await app.set_chat_permissions(chat_id, perm)
except ChatAdminRequired:
- await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`," f"since {BOT_NAME} is not an admin in chat `{chat_id}`")
+ await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_not_admin"].format(chat_id=chat_id, bname=BOT_NAME))
except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_nightmode_{chat_id}")
- await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`," f"since {BOT_NAME} is not present in chat `{chat_id}`" " Removed group from list.")
+ await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_not_present"].format(chat_id=chat_id, bname=BOT_NAME))
except ChatNotModified:
pass
except Exception as e:
- await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to turn off nightmode at `{chat_id}`\n" f"ERROR: `{e}`")
+ await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_off_err"].format(chat_id=chat_id, e=e))
else:
job = scheduler.get_job(f"enable_nightmode_{chat_id}")
close_at = job.next_run_time
- await app.send_message(chat_id, f"#NIGHTMODE_HANDLER\nπ {tglsekarang()}\n\nβοΈ Group is Opening.\nWill be closed at {close_at}", reply_markup=reply_markup)
+ await app.send_message(chat_id, langdict[getlang]["nightmodev2"]["nmd_off_success"].format(dt=tglsekarang(), close_at=close_at), reply_markup=reply_markup)
async def mute_chat(chat_id: int):
+ getlang = await get_db_lang(chat_id)
try:
await app.set_chat_permissions(chat_id, ChatPermissions())
except ChatAdminRequired:
- await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`," f"since {BOT_NAME} is not an admin in chat `{chat_id}`")
+ await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_not_admin"].format(chat_id=chat_id, bname=BOT_NAME))
except (ChannelInvalid, ChannelPrivate):
scheduler.remove_job(f"enable_nightmode_{chat_id}")
scheduler.remove_job(f"disable_nightmode_{chat_id}")
- await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`," f"since {BOT_NAME} is not present in chat `{chat_id}`" " Removed group from list.")
+ await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_not_present"].format(chat_id=chat_id, bname=BOT_NAME))
except ChatNotModified:
pass
except Exception as e:
- await app.send_message(LOG_CHANNEL, f"#NIGHTMODE_FAIL\nFailed to enable nightmode at `{chat_id}`\n" f"ERROR: `{e}`")
+ await app.send_message(LOG_CHANNEL, langdict[getlang]["nightmodev2"]["nmd_on_err"].format(chat_id=chat_id, e=e))
else:
job = scheduler.get_job(f"disable_nightmode_{chat_id}")
open_at = job.next_run_time
- await app.send_message(chat_id, f"#NIGHTMODE_HANDLER\nπ {tglsekarang()}\n\nπ Group is closing.\nWill be opened at {open_at}", reply_markup=reply_markup)
+ await app.send_message(chat_id, langdict[getlang]["nightmodev2"]["nmd_on_success"].format(dt=tglsekarang(), open_at=open_at), reply_markup=reply_markup)
@app.on_message(filters.command("nightmode", COMMAND_HANDLER) & filters.group)
-@adminsOnly("can_change_info")
-async def nightmode_handler(c, msg):
+@require_admin(permissions=["can_change_info"])
+@use_chat_lang()
+async def nightmode_handler(c, msg, strings):
chat_id = msg.chat.id
if "-d" in msg.text:
@@ -134,8 +139,8 @@ async def nightmode_handler(c, msg):
scheduler.remove_job(job_id=f"disable_nightmode_{chat_id}")
if not bool(scheduler.get_jobs()) and bool(scheduler.state):
scheduler.shutdown()
- return await kirimPesan(msg, "Nightmode disabled.")
- return await kirimPesan(msg, "Nightmode isn't enabled in this chat.")
+ return await kirimPesan(msg, strings("nmd_disabled"))
+ return await kirimPesan(msg, strings("nmd_not_enabled"))
starttime = re.findall(r"-s=(\d+:\d+)", msg.text)
start = starttime[0] if starttime else "00:00"
@@ -144,13 +149,13 @@ async def nightmode_handler(c, msg):
try:
start_timestamp = TIME_ZONE.localize(datetime.strptime((now.strftime("%m:%d:%Y - ") + start), "%m:%d:%Y - %H:%M"))
except ValueError:
- return await kirimPesan(msg, "Invalid time format. Use HH:MM format.")
+ return await kirimPesan(msg, strings("invalid_time_format"))
lockdur = re.findall(r"-e=(\w+)", msg.text)
lockdur = lockdur[0] if lockdur else "6h"
lock_dur = extract_time(lockdur.lower())
if not lock_dur:
- return await kirimPesan(msg, "Invalid time duration. Use proper format." "\nExample: 6h (for 6 hours), 10m for 10 minutes.")
+ return await kirimPesan(msg, strings("invalid_lockdur"))
if start_timestamp < now:
start_timestamp = start_timestamp + timedelta(days=1)
@@ -162,13 +167,14 @@ async def nightmode_handler(c, msg):
# schedule to disable nightmode
scheduler.add_job(un_mute_chat, "interval", [chat_id, msg.chat.permissions], id=f"disable_nightmode_{chat_id}", days=1, next_run_time=end_time_stamp, max_instances=50, misfire_grace_time=None)
except ConflictingIdError:
- return await kirimPesan(msg, "Already a schedule is running in this chat. Disable it using `-d` flag.")
- await kirimPesan(msg, "Successfully enabled nightmode in this chat.\n" f'Group will be locked at {start_timestamp.strftime("%H:%M:%S")}' f" and will be opened after {lockdur} everyday.")
+ return await kirimPesan(msg, strings("schedule_already_on"))
+ await kirimPesan(msg, strings("nmd_enable_success").format(st=start_timestamp.strftime("%H:%M:%S"), lockdur=lockdur))
if not bool(scheduler.state):
scheduler.start()
@app.on_callback_query(filters.regex(r"^nightmd$"))
@ratelimiter
-async def callbackanightmd(c, q):
- await q.answer(f"π Hai, Aku {BOT_USERNAME} dibuat menggunakan Framework Pyrogram v{__version__} dan Python 3.10.\n\nMau buat bot seperti ini? Yuuk belajar di @botindonesia\nOwner: @YasirArisM", show_alert=True)
+@use_chat_lang()
+async def callbackanightmd(c, q, strings):
+ await q.answer(strings("nmd_cb").format(bname=c.me.first_name, ver=__version__), show_alert=True)
diff --git a/misskaty/plugins/ocr.py b/misskaty/plugins/ocr.py
index d770bab2..44e6e960 100644
--- a/misskaty/plugins/ocr.py
+++ b/misskaty/plugins/ocr.py
@@ -20,7 +20,7 @@ from misskaty.helper.http import http
from misskaty.vars import COMMAND_HANDLER
__MODULE__ = "OCR"
-__HELP__ = "/ocr [reply to photo] - Read Text From Image"
+__HELP__ = f"/ocr [reply to photo] - Read Text From Image"
@app.on_message(filters.command(["ocr"], COMMAND_HANDLER))
diff --git a/misskaty/plugins/start_help.py b/misskaty/plugins/start_help.py
new file mode 100644
index 00000000..6738760a
--- /dev/null
+++ b/misskaty/plugins/start_help.py
@@ -0,0 +1,292 @@
+"""
+ * @author yasir
+ * @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 οΏ½",
+ 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)
\ No newline at end of file
diff --git a/misskaty/plugins/web_scraper.py b/misskaty/plugins/web_scraper.py
index 89319c4d..656a4497 100644
--- a/misskaty/plugins/web_scraper.py
+++ b/misskaty/plugins/web_scraper.py
@@ -11,6 +11,7 @@ from pykeyboard import InlineKeyboard, InlineButton
from pyrogram import filters
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
+from misskaty.helper.localization import use_chat_lang
from misskaty.helper.kuso_utils import Kusonime
from misskaty import app
from misskaty.vars import COMMAND_HANDLER
@@ -47,11 +48,11 @@ def split_arr(arr, size: 5):
# Terbit21 GetData
-async def getDataTerbit21(msg, kueri, CurrentPage):
+async def getDataTerbit21(msg, kueri, CurrentPage, strings):
if not SCRAP_DICT.get(msg.id):
terbitjson = (await http.get(f"https://yasirapi.eu.org/terbit21?q={kueri}")).json() if kueri else (await http.get("https://yasirapi.eu.org/terbit21")).json()
if not terbitjson.get("result"):
- await editPesan(msg, "Sorry, could not find any results!")
+ await editPesan(msg, strings("no_result"))
return None, None
SCRAP_DICT[msg.id] = [split_arr(terbitjson["result"], 6), kueri]
try:
@@ -59,25 +60,25 @@ async def getDataTerbit21(msg, kueri, CurrentPage):
PageLen = len(SCRAP_DICT[msg.id][0])
if kueri:
- TerbitRes = f"#Terbit21 Results For: {kueri}\n\n"
+ TerbitRes = strings("header_with_query").format(web="Terbit21", kueri=kueri)
else:
- TerbitRes = "#Terbit21 Latest:\nπ Use /terbit21 [title] to start search with title.\n\n"
+ TerbitRes = strings("header_no_query").format(web="Terbit21", cmd="terbit21")
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
- TerbitRes += f"{c}. {i['judul']}\nCategory: {i['kategori']}\n"
- TerbitRes += "\n" if re.search(r"Complete|Ongoing", i["kategori"]) else f"π Download\n\n"
+ TerbitRes += f"{c}. {i['judul']}\n{strings('cat_text')}: {i['kategori']}\n"
+ TerbitRes += "\n" if re.search(r"Complete|Ongoing", i["kategori"]) else f"{strings('dl_text')}\n\n"
TerbitRes = "".join(i for i in TerbitRes if i not in "[]")
return TerbitRes, PageLen
except (IndexError, KeyError):
- await editPesan(msg, "Sorry, could not find any results!")
+ await editPesan(msg, strings("no_result"))
return None, None
# LK21 GetData
-async def getDatalk21(msg, kueri, CurrentPage):
+async def getDatalk21(msg, kueri, CurrentPage, strings):
if not SCRAP_DICT.get(msg.id):
lk21json = (await http.get(f"https://yasirapi.eu.org/lk21?q={kueri}")).json() if kueri else (await http.get("https://yasirapi.eu.org/lk21")).json()
if not lk21json.get("result"):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, None
SCRAP_DICT[msg.id] = [split_arr(lk21json["result"], 6), kueri]
try:
@@ -85,46 +86,46 @@ async def getDatalk21(msg, kueri, CurrentPage):
PageLen = len(SCRAP_DICT[msg.id][0])
if kueri:
- lkResult = f"#Layarkaca21 Results For: {kueri}\n\n"
+ lkResult = strings("header_with_query").format(web="Layarkaca21", kueri=kueri)
else:
- lkResult = "#Layarkaca21 Latest:\nπ Use /lk21 [title] to start search with title.\n\n"
+ lkResult = strings("header_no_query").format(web="Layarkaca21", cmd="lk21")
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
- lkResult += f"{c}. {i['judul']}\nCategory: {i['kategori']}\n"
- lkResult += "\n" if re.search(r"Complete|Ongoing", i["kategori"]) else f"π Download\n\n"
+ lkResult += f"{c}. {i['judul']}\n{strings('cat_text')}: {i['kategori']}\n"
+ lkResult += "\n" if re.search(r"Complete|Ongoing", i["kategori"]) else f"{strings('dl_text')}\n\n"
lkResult = "".join(i for i in lkResult if i not in "[]")
return lkResult, PageLen
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, None
# Pahe GetData
-async def getDataPahe(msg, kueri, CurrentPage):
+async def getDataPahe(msg, kueri, CurrentPage, strings):
if not SCRAP_DICT.get(msg.id):
pahejson = (await http.get(f"https://yasirapi.eu.org/pahe?q={kueri}")).json()
if not pahejson.get("result"):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, None
SCRAP_DICT[msg.id] = [split_arr(pahejson["result"], 6), kueri]
try:
index = int(CurrentPage - 1)
PageLen = len(SCRAP_DICT[msg.id][0])
- paheResult = f"#Pahe Results For: {kueri}\n\n" if kueri else f"#Pahe Latest:\nπ Use /pahe [title] to start search with title.\n\n"
+ paheResult = strings("header_with_query").format(web="Pahe", kueri=kueri) if kueri else strings("header_no_query").format(web="Pahe", cmd="pahe")
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
paheResult += f"{c}. {i['judul']}\n\n"
paheResult = "".join(i for i in paheResult if i not in "[]")
return paheResult, PageLen
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, None
# Kusonime GetData
-async def getDataKuso(msg, kueri, CurrentPage, user):
+async def getDataKuso(msg, kueri, CurrentPage, user, strings):
if not SCRAP_DICT.get(msg.id):
kusodata = []
- data = await http.get(f"https://kusonime.com/?s={kueri}", headers=headers)
+ data = await http.get(f"https://kusonime.com/?s={kueri}", headers=headers, follow_redirects=True)
res = BeautifulSoup(data, "lxml").find_all("h2", {"class": "episodeye"})
for i in res:
ress = i.find_all("a")[0]
@@ -132,7 +133,7 @@ async def getDataKuso(msg, kueri, CurrentPage, user):
link = ress["href"]
kusodata.append({"title": title, "link": link})
if not kusodata:
- await editPesan(msg, "Sorry could not find any results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None, None
SCRAP_DICT[msg.id] = [split_arr(kusodata, 10), kueri]
try:
@@ -141,7 +142,7 @@ async def getDataKuso(msg, kueri, CurrentPage, user):
extractbtn1 = []
extractbtn2 = []
- kusoResult = f"#Kusonime Latest Post\n\n" if kueri == "" else f"#Kusonime Results For: {kueri}\n\n"
+ kusoResult = strings("header_no_query").format(web="Kusonime", cmd="kusonime") if kueri == "" else strings("header_with_query").format(web="Kusonime", kueri=kueri)
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
kusoResult += f"{c}. {i['title']}\n{i['link']}\n\n"
if c < 6:
@@ -151,15 +152,15 @@ async def getDataKuso(msg, kueri, CurrentPage, user):
kusoResult = "".join(i for i in kusoResult if i not in "[]")
return kusoResult, PageLen, extractbtn1, extractbtn2
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None, None
# Movieku GetData
-async def getDataMovieku(msg, kueri, CurrentPage):
+async def getDataMovieku(msg, kueri, CurrentPage, strings):
if not SCRAP_DICT.get(msg.id):
moviekudata = []
- data = await http.get(f"https://107.152.37.223/?s={kueri}", headers=headers)
+ data = await http.get(f"https://107.152.37.223/?s={kueri}", headers=headers, follow_redirects=True)
r = BeautifulSoup(data, "lxml")
res = r.find_all(class_="bx")
for i in res:
@@ -169,35 +170,35 @@ async def getDataMovieku(msg, kueri, CurrentPage):
typee = typ.strip() if typ.strip() != "" else "~"
moviekudata.append({"judul": judul, "link": link, "type": typee})
if not moviekudata:
- await editPesan(msg, "Sorry could not find any results!")
+ await editPesan(msg, strings("no_result"))
return None, None
SCRAP_DICT[msg.id] = [split_arr(moviekudata, 6), kueri]
try:
index = int(CurrentPage - 1)
PageLen = len(SCRAP_DICT[msg.id][0])
- moviekuResult = f"#Movieku Latest:\nπ Use /movieku [title] to start search with title.\n\n" if kueri == "" else f"#Movieku Results For: {kueri}\n\n"
+ moviekuResult = strings("header_no_query").format(web="Movieku", cmd="movieku") if kueri == "" else strings("header_with_query").format(web="Movieku", kueri=kueri)
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
- moviekuResult += f"{c}. {i['judul']}\nQuality/Status: {i['type']}\nExtract: /movieku_scrap {i['link']}\n\n"
+ moviekuResult += f"{c}. {i['judul']}\n{strings('quality')}/Status: {i['type']}\nExtract: /movieku_scrap {i['link']}\n\n"
moviekuResult = "".join(i for i in moviekuResult if i not in "[]")
return moviekuResult, PageLen
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, None
# Savefilm21 GetData
-async def getDataSavefilm21(msg, kueri, CurrentPage, user):
+async def getDataSavefilm21(msg, kueri, CurrentPage, user, strings):
if not SCRAP_DICT.get(msg.id):
sfdata = []
- data = await http.get(f"https://savefilm21.pro/?s={kueri}", headers=headers)
+ data = await http.get(f"https://savefilm21.pro/?s={kueri}", headers=headers, follow_redirects=True)
text = BeautifulSoup(data, "lxml")
entry = text.find_all(class_="entry-header")
if "Tidak Ditemukan" in entry[0].text:
if not kueri:
- await editPesan(msg, "Sorry, could not find any result")
+ await editPesan(msg, strings("no_result"))
else:
- await editPesan(msg, f"Sorry, could not find any result for: {kueri}")
+ await editPesan(msg, strings("no_result_w_query").format(kueri=kueri))
return None, 0, None
for i in entry:
genre = i.find(class_="gmr-movie-on").text
@@ -210,21 +211,21 @@ async def getDataSavefilm21(msg, kueri, CurrentPage, user):
index = int(CurrentPage - 1)
PageLen = len(SCRAP_DICT[msg.id][0])
extractbtn = []
- sfResult = f"#SaveFilm21 Latest:\nπ Use /savefilm21 [title] to start search with title.\n\n" if kueri == "" else f"#Savefilm21 Results For: {kueri}\n\n"
+ sfResult = strings("header_no_query").format(web="Savefilm21", cmd="savefilm21") if kueri == "" else strings("header_with_query").format(web="Savefilm21", kueri=kueri)
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
sfResult += f"{c}. {i['judul']}\nGenre: {i['genre']}\n\n"
extractbtn.append(InlineButton(c, f"sf21extract#{CurrentPage}#{c}#{user}#{msg.id}"))
sfResult = "".join(i for i in sfResult if i not in "[]")
return sfResult, PageLen, extractbtn
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None
# Lendrive GetData
-async def getDataLendrive(msg, kueri, CurrentPage, user):
+async def getDataLendrive(msg, kueri, CurrentPage, user, strings):
if not SCRAP_DICT.get(msg.id):
- data = await http.get(f"https://lendrive.web.id/?s={kueri}", headers=headers)
+ data = await http.get(f"https://lendrive.web.id/?s={kueri}", headers=headers, follow_redirects=True)
soup = BeautifulSoup(data, "lxml")
lenddata = []
for o in soup.find_all(class_="bsx"):
@@ -234,7 +235,7 @@ async def getDataLendrive(msg, kueri, CurrentPage, user):
kualitas = o.find(class_="typez TV").text if o.find(class_="typez TV") else o.find(class_="typez BD")
lenddata.append({"judul": title, "link": link, "quality": kualitas, "status": status})
if not lenddata:
- await editPesan(msg, "Sorry could not find any results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None
SCRAP_DICT[msg.id] = [split_arr(lenddata, 6), kueri]
try:
@@ -242,21 +243,21 @@ async def getDataLendrive(msg, kueri, CurrentPage, user):
PageLen = len(SCRAP_DICT[msg.id][0])
extractbtn = []
- lenddataResult = f"#LenDrive Latest:\nπ Use /lendrive [title] to start search with title.\n\n" if kueri == "" else f"#LenDrive Results For: {kueri}\n\n"
+ lenddataResult = strings("header_no_query").format(web="Lendrive", cmd="lendrive") if kueri == "" else strings("header_with_query").format(web="Lendrive", kueri=kueri)
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
- lenddataResult += f"{c}. {i['judul']}\nQuality: {i['quality']}\nStatus: {i['status']}\n\n"
+ lenddataResult += f"{c}. {i['judul']}\n{strings('quality')}: {i['quality']}\nStatus: {i['status']}\n\n"
extractbtn.append(InlineButton(c, f"lendriveextract#{CurrentPage}#{c}#{user}#{msg.id}"))
lenddataResult = "".join(i for i in lenddataResult if i not in "[]")
return lenddataResult, PageLen, extractbtn
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None
# MelongMovie GetData
-async def getDataMelong(msg, kueri, CurrentPage, user):
+async def getDataMelong(msg, kueri, CurrentPage, user, strings):
if not SCRAP_DICT.get(msg.id):
- data = await http.get(f"https://melongmovie.info/?s={kueri}", headers=headers)
+ data = await http.get(f"https://melongmovie.info/?s={kueri}", headers=headers, follow_redirects=True)
bs4 = BeautifulSoup(data, "lxml")
melongdata = []
for res in bs4.select(".box"):
@@ -269,7 +270,7 @@ async def getDataMelong(msg, kueri, CurrentPage, user):
quality = "N/A"
melongdata.append({"judul": title, "link": url, "quality": quality})
if not melongdata:
- await editPesan(msg, "Sorry could not find any results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None
SCRAP_DICT[msg.id] = [split_arr(melongdata, 6), kueri]
try:
@@ -277,28 +278,28 @@ async def getDataMelong(msg, kueri, CurrentPage, user):
PageLen = len(SCRAP_DICT[msg.id][0])
extractbtn = []
- melongResult = f"#MelongMovie Latest:\nπ Use /melongmovie [title] to start search with title.\n\n" if kueri == "" else f"#MelongMovie Results For: {kueri}\n\n"
+ melongResult = strings("header_no_query").format(web="Melongmovie", cmd="melongmovie") if kueri == "" else strings("header_with_query").format(web="Melongmovie", kueri=kueri)
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
- melongResult += f"{c}. {i['judul']}\nQuality: {i['quality']}\n\n"
+ melongResult += f"{c}. {i['judul']}\n{strings('quality')}: {i['quality']}\n\n"
extractbtn.append(InlineButton(c, f"melongextract#{CurrentPage}#{c}#{user}#{msg.id}"))
melongResult = "".join(i for i in melongResult if i not in "[]")
return melongResult, PageLen, extractbtn
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None
# GoMov GetData
-async def getDataGomov(msg, kueri, CurrentPage, user):
+async def getDataGomov(msg, kueri, CurrentPage, user, strings):
if not SCRAP_DICT.get(msg.id):
- gomovv = await http.get(f"https://gomov.club/?s={kueri}", headers=headers)
+ gomovv = await http.get(f"https://gomov.cfd/?s={kueri}", headers=headers, follow_redirects=True)
text = BeautifulSoup(gomovv, "lxml")
entry = text.find_all(class_="entry-header")
if entry[0].text.strip() == "Nothing Found":
if not kueri:
- await editPesan(msg, "Sorry, i could not find anything.")
+ await editPesan(msg, strings("no_result"))
else:
- await editPesan(msg, f"Sorry, i could not find query: {kueri}")
+ await editPesan(msg, strings("no_result_w_query"))
return None, 0, None
data = []
for i in entry:
@@ -313,420 +314,438 @@ async def getDataGomov(msg, kueri, CurrentPage, user):
PageLen = len(SCRAP_DICT[msg.id][0])
extractbtn = []
- gomovResult = f"#Gomov Results For: {kueri}\n\n" if kueri else f"#Gomov Latest:\nπ Use /gomov [title] to start search with title.\n\n"
+ gomovResult = strings("header_with_query").format(web="GoMov", kueri=kueri) if kueri else strings("header_no_query").format(web="GoMov", cmd="gomov")
for c, i in enumerate(SCRAP_DICT[msg.id][0][index], start=1):
gomovResult += f"{c}. {i['judul']}\nGenre: {i['genre']}\n\n"
if not re.search(r"Series", i["genre"]):
extractbtn.append(InlineButton(c, f"gomovextract#{CurrentPage}#{c}#{user}#{msg.id}"))
- gomovResult += "Some result will not appear in extract button because unsupported link."
+ gomovResult += strings("unsupport_dl_btn")
gomovResult = "".join(i for i in gomovResult if i not in "[]")
return gomovResult, PageLen, extractbtn
except (IndexError, KeyError):
- await editPesan(msg, "Sorry could not find any matching results!")
+ await editPesan(msg, strings("no_result"))
return None, 0, None
# Terbit21 CMD
@app.on_message(filters.command(["terbit21"], COMMAND_HANDLER))
@ratelimiter
-async def terbit21_s(client, message):
+@use_chat_lang()
+async def terbit21_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = None
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Terbit21..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- terbitres, PageLen = await getDataTerbit21(pesan, kueri, CurrentPage)
+ terbitres, PageLen = await getDataTerbit21(pesan, kueri, CurrentPage, strings)
if not terbitres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_terbit21#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, terbitres, reply_markup=keyboard)
# LK21 CMD
@app.on_message(filters.command(["lk21"], COMMAND_HANDLER))
@ratelimiter
-async def lk21_s(client, message):
+@use_chat_lang()
+async def lk21_s(client, message, strings):
message.chat.id
kueri = " ".join(message.command[1:])
if not kueri:
kueri = None
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from LK21..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- lkres, PageLen = await getDatalk21(pesan, kueri, CurrentPage)
+ lkres, PageLen = await getDatalk21(pesan, kueri, CurrentPage, strings)
if not lkres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_lk21#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, lkres, disable_web_page_preview=True, reply_markup=keyboard)
# Pahe CMD
@app.on_message(filters.command(["pahe"], COMMAND_HANDLER))
@ratelimiter
-async def pahe_s(client, message):
+@use_chat_lang()
+async def pahe_s(client, message, strings):
message.chat.id
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Pahe Web..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- paheres, PageLen = await getDataPahe(pesan, kueri, CurrentPage)
+ paheres, PageLen = await getDataPahe(pesan, kueri, CurrentPage, strings)
if not paheres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_pahe#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, paheres, disable_web_page_preview=True, reply_markup=keyboard)
# Gomov CMD
@app.on_message(filters.command(["gomov"], COMMAND_HANDLER))
@ratelimiter
-async def gomov_s(client, message):
+@use_chat_lang()
+async def gomov_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data Gomov Web..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- gomovres, PageLen, btn = await getDataGomov(pesan, kueri, CurrentPage, message.from_user.id)
+ gomovres, PageLen, btn = await getDataGomov(pesan, kueri, CurrentPage, message.from_user.id, strings)
if not gomovres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_gomov#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=message.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, gomovres, disable_web_page_preview=True, reply_markup=keyboard)
# MelongMovie CMD
@app.on_message(filters.command(["melongmovie"], COMMAND_HANDLER))
@ratelimiter
-async def melong_s(client, message):
+@use_chat_lang()
+async def melong_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Melongmovie..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- melongres, PageLen, btn = await getDataMelong(pesan, kueri, CurrentPage, message.from_user.id)
+ melongres, PageLen, btn = await getDataMelong(pesan, kueri, CurrentPage, message.from_user.id, strings)
if not melongres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_melong#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=message.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, melongres, disable_web_page_preview=True, reply_markup=keyboard)
# Savefilm21 CMD
@app.on_message(filters.command(["savefilm21"], COMMAND_HANDLER))
@ratelimiter
-async def savefilm_s(client, message):
+@use_chat_lang()
+async def savefilm_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Savefilm21..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- savefilmres, PageLen, btn = await getDataSavefilm21(pesan, kueri, CurrentPage, message.from_user.id)
+ savefilmres, PageLen, btn = await getDataSavefilm21(pesan, kueri, CurrentPage, message.from_user.id, strings)
if not savefilmres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_savefilm#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=message.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, savefilmres, disable_web_page_preview=True, reply_markup=keyboard)
# Kusonime CMD
@app.on_message(filters.command(["kusonime"], COMMAND_HANDLER))
@ratelimiter
-async def kusonime_s(client, message):
+@use_chat_lang()
+async def kusonime_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Kusonime..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- kusores, PageLen, btn1, btn2 = await getDataKuso(pesan, kueri, CurrentPage, message.from_user.id)
+ kusores, PageLen, btn1, btn2 = await getDataKuso(pesan, kueri, CurrentPage, message.from_user.id, strings)
if not kusores:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_kuso#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=message.from_user.id))
keyboard.row(*btn1)
if btn2:
keyboard.row(*btn2)
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, kusores, disable_web_page_preview=True, reply_markup=keyboard)
# Lendrive CMD
@app.on_message(filters.command(["lendrive"], COMMAND_HANDLER))
@ratelimiter
-async def lendrive_s(client, message):
+@use_chat_lang()
+async def lendrive_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Lendrive..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- lendres, PageLen, btn = await getDataLendrive(pesan, kueri, CurrentPage, message.from_user.id)
+ lendres, PageLen, btn = await getDataLendrive(pesan, kueri, CurrentPage, message.from_user.id, strings)
if not lendres:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_lendrive#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=message.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, lendres, disable_web_page_preview=True, reply_markup=keyboard)
# Movieku CMD
@app.on_message(filters.command(["movieku"], COMMAND_HANDLER))
@ratelimiter
-async def movieku_s(client, message):
+@use_chat_lang()
+async def movieku_s(client, message, strings):
kueri = " ".join(message.command[1:])
if not kueri:
kueri = ""
- pesan = await kirimPesan(message, "β³ Please wait, scraping data from Movieku..", quote=True)
+ pesan = await kirimPesan(message, strings("get_data"), quote=True)
CurrentPage = 1
- moviekures, PageLen = await getDataMovieku(pesan, kueri, CurrentPage)
+ moviekures, PageLen = await getDataMovieku(pesan, kueri, CurrentPage, strings)
if not moviekures:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_movieku#{number}" + f"#{pesan.id}#{message.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{message.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{message.from_user.id}"))
await editPesan(pesan, moviekures, disable_web_page_preview=True, reply_markup=keyboard)
# Savefillm21 Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_savefilm#" in query.data))
@ratelimiter
-async def savefilmpage_callback(client, callback_query):
+@use_chat_lang()
+async def savefilmpage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- savefilmres, PageLen, btn = await getDataSavefilm21(callback_query.message, kueri, CurrentPage, callback_query.from_user.id)
+ savefilmres, PageLen, btn = await getDataSavefilm21(callback_query.message, kueri, CurrentPage, callback_query.from_user.id, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_savefilm#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=callback_query.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, savefilmres, disable_web_page_preview=True, reply_markup=keyboard)
# Kuso Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_kuso#" in query.data))
@ratelimiter
-async def kusopage_callback(client, callback_query):
+@use_chat_lang()
+async def kusopage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- kusores, PageLen, btn1, btn2 = await getDataKuso(callback_query.message, kueri, CurrentPage, callback_query.from_user.id)
+ kusores, PageLen, btn1, btn2 = await getDataKuso(callback_query.message, kueri, CurrentPage, callback_query.from_user.id, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_kuso#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=callback_query.from_user.id))
keyboard.row(*btn1)
if btn2:
keyboard.row(*btn2)
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, kusores, disable_web_page_preview=True, reply_markup=keyboard)
# Lendrive Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_lendrive#" in query.data))
@ratelimiter
-async def moviekupage_callback(client, callback_query):
+@use_chat_lang()
+async def moviekupage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- lendres, PageLen, btn = await getDataLendrive(callback_query.message, kueri, CurrentPage, callback_query.from_user.id)
+ lendres, PageLen, btn = await getDataLendrive(callback_query.message, kueri, CurrentPage, callback_query.from_user.id, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_lendrive#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=callback_query.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, lendres, disable_web_page_preview=True, reply_markup=keyboard)
# Movieku Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_movieku#" in query.data))
@ratelimiter
-async def moviekupage_callback(client, callback_query):
+@use_chat_lang()
+async def moviekupage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- moviekures, PageLen = await getDataMovieku(callback_query.message, kueri, CurrentPage)
+ moviekures, PageLen = await getDataMovieku(callback_query.message, kueri, CurrentPage, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_movieku#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, moviekures, disable_web_page_preview=True, reply_markup=keyboard)
# Terbit21 Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_terbit21#" in query.data))
@ratelimiter
-async def terbit21page_callback(client, callback_query):
+@use_chat_lang()
+async def terbit21page_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- terbitres, PageLen = await getDataTerbit21(callback_query.message, kueri, CurrentPage)
+ terbitres, PageLen = await getDataTerbit21(callback_query.message, kueri, CurrentPage, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_terbit21#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, terbitres, disable_web_page_preview=True, reply_markup=keyboard)
# Page Callback Melong
@app.on_callback_query(filters.create(lambda _, __, query: "page_melong#" in query.data))
@ratelimiter
-async def melongpage_callback(client, callback_query):
+@use_chat_lang()
+async def melongpage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- terbitres, PageLen, btn = await getDataMelong(callback_query.message, kueri, CurrentPage, callback_query.from_user.id)
+ terbitres, PageLen, btn = await getDataMelong(callback_query.message, kueri, CurrentPage, callback_query.from_user.id, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_melong#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=callback_query.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, terbitres, disable_web_page_preview=True, reply_markup=keyboard)
# Lk21 Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_lk21#" in query.data))
@ratelimiter
-async def lk21page_callback(client, callback_query):
+@use_chat_lang()
+async def lk21page_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- lkres, PageLen = await getDatalk21(callback_query.message, kueri, CurrentPage)
+ lkres, PageLen = await getDatalk21(callback_query.message, kueri, CurrentPage, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_lk21#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, lkres, disable_web_page_preview=True, reply_markup=keyboard)
# Pahe Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_pahe#" in query.data))
@ratelimiter
-async def pahepage_callback(client, callback_query):
+@use_chat_lang()
+async def pahepage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- lkres, PageLen = await getDataPahe(callback_query.message, kueri, CurrentPage)
+ lkres, PageLen = await getDataPahe(callback_query.message, kueri, CurrentPage, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_pahe#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, lkres, disable_web_page_preview=True, reply_markup=keyboard)
# Gomov Page Callback
@app.on_callback_query(filters.create(lambda _, __, query: "page_gomov#" in query.data))
@ratelimiter
-async def gomovpage_callback(client, callback_query):
+@use_chat_lang()
+async def gomovpage_callback(client, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
message_id = int(callback_query.data.split("#")[2])
CurrentPage = int(callback_query.data.split("#")[1])
try:
kueri = SCRAP_DICT[message_id][1]
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
try:
- gomovres, PageLen, btn = await getDataGomov(callback_query.message, kueri, CurrentPage, callback_query.from_user.id)
+ gomovres, PageLen, btn = await getDataGomov(callback_query.message, kueri, CurrentPage, callback_query.from_user.id, strings)
except TypeError:
return
keyboard = InlineKeyboard()
keyboard.paginate(PageLen, CurrentPage, "page_gomov#{number}" + f"#{message_id}#{callback_query.from_user.id}")
- keyboard.row(InlineButton("π Extract Data ", "Hmmm"))
+ keyboard.row(InlineButton(strings("ex_data"), user_id=callback_query.from_user.id))
keyboard.row(*btn)
- keyboard.row(InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
await editPesan(callback_query.message, gomovres, disable_web_page_preview=True, reply_markup=keyboard)
@@ -734,24 +753,25 @@ async def gomovpage_callback(client, callback_query):
# Kusonime DDL
@app.on_callback_query(filters.create(lambda _, __, query: "kusoextract#" in query.data))
@ratelimiter
-async def kusonime_scrap(_, callback_query):
+@use_chat_lang()
+async def kusonime_scrap(_, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
idlink = int(callback_query.data.split("#")[2])
message_id = int(callback_query.data.split("#")[4])
CurrentPage = int(callback_query.data.split("#")[1])
try:
link = SCRAP_DICT[message_id][0][CurrentPage - 1][idlink - 1].get("link")
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
kuso = Kusonime()
keyboard = InlineKeyboard()
- keyboard.row(InlineButton("β©οΈ Back", f"page_kuso#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("back_btn"), f"page_kuso#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
try:
if init_url := data_kuso.get(link, None):
ph = init_url.get("ph_url")
- await editPesan(callback_query.message, f"Scrape result from {link}:\n\n{ph}", reply_markup=keyboard, disable_web_page_preview=False)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=ph), reply_markup=keyboard, disable_web_page_preview=False)
return
tgh = await kuso.telegraph(link, message_id)
if tgh["error"]:
@@ -761,25 +781,26 @@ async def kusonime_scrap(_, callback_query):
await editPesan(callback_query.message, f"ERROR: {err}", reply_markup=keyboard)
return
data_kuso[link] = {"ph_url": tgh["url"]}
- await editPesan(callback_query.message, f"Scrape result from {link}:\n\n{tgh['url']}", reply_markup=keyboard, disable_web_page_preview=False)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=tgh['url']), reply_markup=keyboard, disable_web_page_preview=False)
# Savefilm21 DDL
@app.on_callback_query(filters.create(lambda _, __, query: "sf21extract#" in query.data))
@ratelimiter
-async def savefilm21_scrap(_, callback_query):
+@use_chat_lang()
+async def savefilm21_scrap(_, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
idlink = int(callback_query.data.split("#")[2])
message_id = int(callback_query.data.split("#")[4])
CurrentPage = int(callback_query.data.split("#")[1])
try:
link = SCRAP_DICT[message_id][0][CurrentPage - 1][idlink - 1].get("link")
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
keyboard = InlineKeyboard()
- keyboard.row(InlineButton("β©οΈ Back", f"page_savefilm#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("back_btn"), f"page_savefilm#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
try:
html = await http.get(link, headers=headers)
soup = BeautifulSoup(html.text, "lxml")
@@ -788,13 +809,14 @@ async def savefilm21_scrap(_, callback_query):
except Exception as err:
await editPesan(callback_query.message, f"ERROR: {err}", reply_markup=keyboard)
return
- await editPesan(callback_query.message, f"Scrape result from {link}:\n\n{res}", reply_markup=keyboard)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=res), reply_markup=keyboard)
# Scrape Link Download Movieku.CC
@app.on_message(filters.command(["movieku_scrap"], COMMAND_HANDLER))
@ratelimiter
-async def muviku_scrap(_, message):
+@use_chat_lang()
+async def muviku_scrap(_, message, strings):
try:
link = message.text.split(" ", maxsplit=1)[1]
html = await http.get(link, headers=headers)
@@ -808,11 +830,11 @@ async def muviku_scrap(_, message):
# print(f"{kualitas}\n{link
data.append({"link": link, "kualitas": kualitas})
if not data:
- return await message.reply("Oops, data film tidak ditemukan.")
+ return await message.reply(strings("no_result"))
res = "".join(f"Host: {i['kualitas']}\n{i['link']}\n\n" for i in data)
await message.reply(res)
except IndexError:
- return await message.reply(f"Gunakan command /{message.command[0]} [link] untuk scrap link download")
+ return await message.reply(strings("invalid_cmd_scrape").format(cmd=message.command[0]))
except Exception as e:
await message.reply(f"ERROR: {str(e)}")
@@ -820,19 +842,20 @@ async def muviku_scrap(_, message):
# Scrape DDL Link Melongmovie
@app.on_callback_query(filters.create(lambda _, __, query: "melongextract#" in query.data))
@ratelimiter
-async def melong_scrap(_, callback_query):
+@use_chat_lang()
+async def melong_scrap(_, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("uauth"), True)
idlink = int(callback_query.data.split("#")[2])
message_id = int(callback_query.data.split("#")[4])
CurrentPage = int(callback_query.data.split("#")[1])
try:
link = SCRAP_DICT[message_id][0][CurrentPage - 1][idlink - 1].get("link")
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
keyboard = InlineKeyboard()
- keyboard.row(InlineButton("β©οΈ Back", f"page_melong#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("back_btn"), f"page_melong#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
try:
html = await http.get(link, headers=headers)
soup = BeautifulSoup(html.text, "lxml")
@@ -844,25 +867,26 @@ async def melong_scrap(_, callback_query):
except Exception as err:
await editPesan(callback_query.message, f"ERROR: {err}", reply_markup=keyboard)
return
- await editPesan(callback_query.message, f"Scrape result from {link}:\n\n{rep}", reply_markup=keyboard)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=rep), reply_markup=keyboard)
# Scrape DDL Link Gomov
@app.on_callback_query(filters.create(lambda _, __, query: "gomovextract#" in query.data))
@ratelimiter
-async def gomov_dl(_, callback_query):
+@use_chat_lang()
+async def gomov_dl(_, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
idlink = int(callback_query.data.split("#")[2])
message_id = int(callback_query.data.split("#")[4])
CurrentPage = int(callback_query.data.split("#")[1])
try:
link = SCRAP_DICT[message_id][0][CurrentPage - 1][idlink - 1].get("link")
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
keyboard = InlineKeyboard()
- keyboard.row(InlineButton("β©οΈ Back", f"page_gomov#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("back_btn"), f"page_gomov#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
try:
html = await http.get(link, headers=headers)
soup = BeautifulSoup(html.text, "lxml")
@@ -875,34 +899,35 @@ async def gomov_dl(_, callback_query):
except Exception as err:
await editPesan(callback_query.message, f"ERROR: {err}", reply_markup=keyboard)
return
- await editPesan(callback_query.message, f"Scrape result from {link}:\n\n{hasil}", reply_markup=keyboard)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=hasil), reply_markup=keyboard)
@app.on_callback_query(filters.create(lambda _, __, query: "lendriveextract#" in query.data))
@ratelimiter
-async def lendrive_dl(_, callback_query):
+@use_chat_lang()
+async def lendrive_dl(_, callback_query, strings):
if callback_query.from_user.id != int(callback_query.data.split("#")[3]):
- return await callback_query.answer("Not yours..", True)
+ return await callback_query.answer(strings("unauth"), True)
idlink = int(callback_query.data.split("#")[2])
message_id = int(callback_query.data.split("#")[4])
CurrentPage = int(callback_query.data.split("#")[1])
try:
link = SCRAP_DICT[message_id][0][CurrentPage - 1][idlink - 1].get("link")
except KeyError:
- return await callback_query.answer("Invalid callback data, please send CMD again..")
+ return await callback_query.answer(strings("invalid_cb"))
keyboard = InlineKeyboard()
- keyboard.row(InlineButton("β©οΈ Back", f"page_lendrive#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton("β Close", f"close#{callback_query.from_user.id}"))
+ keyboard.row(InlineButton(strings("back_btn"), f"page_lendrive#{CurrentPage}#{message_id}#{callback_query.from_user.id}"), InlineButton(strings("cl_btn"), f"close#{callback_query.from_user.id}"))
try:
hmm = await http.get(link, headers=headers)
q = BeautifulSoup(hmm.text, "lxml")
j = q.findAll("div", class_="soraurlx")
- kl = "#Lendrive Results Download URL:\n\n"
+ kl = ""
for i in j:
if not i.find("a"):
continue
kl += f"{i.find('strong')}:\n"
kl += "".join(f"[ {a.text} ]\n" for a in i.findAll("a"))
- await editPesan(callback_query.message, f"Scrape result from {link}:\n\n{kl}", reply_markup=keyboard)
+ await editPesan(callback_query.message, strings("res_scrape").format(link=link, kl=kl), reply_markup=keyboard)
except Exception as err:
await editPesan(callback_query.message, f"ERROR: {err}", reply_markup=keyboard)
diff --git a/misskaty/plugins/ytdl_download_new.py b/misskaty/plugins/ytdl_plugins.py
similarity index 78%
rename from misskaty/plugins/ytdl_download_new.py
rename to misskaty/plugins/ytdl_plugins.py
index 6f1e691d..49cd4d0f 100644
--- a/misskaty/plugins/ytdl_download_new.py
+++ b/misskaty/plugins/ytdl_plugins.py
@@ -11,6 +11,7 @@ from misskaty.core.message_utils import *
from misskaty.core.decorator.errors import capture_err
from misskaty.core.decorator.ratelimiter import ratelimiter
from misskaty.helper.http import http
+from misskaty.helper.localization import use_chat_lang
from misskaty.vars import COMMAND_HANDLER, LOG_CHANNEL
LOGGER = getLogger(__name__)
@@ -25,23 +26,21 @@ def rand_key():
@app.on_message(filters.command(["ytsearch"], COMMAND_HANDLER) & ~filters.channel)
@capture_err
@ratelimiter
-async def ytsearch(_, message):
+@use_chat_lang()
+async def ytsearch(_, message, strings):
if message.sender_chat:
- return await kirimPesan(message, "This feature not supported for channel.")
+ return await kirimPesan(message, strings("no_channel"))
if len(message.command) == 1:
- return await kirimPesan(message, "Please input a query..!")
+ return await kirimPesan(message, strings("no_query"))
query = message.text.split(" ", maxsplit=1)[1]
search_key = rand_key()
YT_DB[search_key] = query
search = await main.VideosSearch(query).next()
if search["result"] == []:
- return await message.reply(f"No result found for `{query}`")
+ return await message.reply(strings("no_res").format(kweri=query))
i = search["result"][0]
- out = f"{i['title']}"
- out += f"\nPublished {i['publishedTime']}\n"
- out += f"\nβ― Duration: {i['duration']}"
- out += f"\nβ― Views: {i['viewCount']['short']}"
- out += f"\nβ― Uploader: {i['channel']['name']}\n\n"
+ out = f"{i['title']}\n"
+ out = strings("yts_msg").format(pub=i['publishedTime'], dur=i['duration'], vi=i['viewCount']['short'], clink=i['channel']['link'], cname=i['channel']['name'])
btn = InlineKeyboardMarkup(
[
[
@@ -50,7 +49,7 @@ async def ytsearch(_, message):
callback_data=f"ytdl_scroll|{search_key}|1",
)
],
- [InlineKeyboardButton("Download", callback_data=f"yt_gen|{i['id']}")],
+ [InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")],
]
)
img = await get_ytthumb(i["id"])
@@ -62,17 +61,18 @@ async def ytsearch(_, message):
@app.on_message(filters.command(["ytdown"], COMMAND_HANDLER))
@capture_err
@ratelimiter
-async def ytdownv2(_, message):
+@use_chat_lang()
+async def ytdownv2(_, message, strings):
if not message.from_user:
- return
+ return await kirimPesan(message, strings("no_channel"))
if len(message.command) == 1:
- return await message.reply("Please input a valid YT-DLP Supported URL")
+ return await message.reply(strings("invalid_link"))
url = message.text.split(" ", maxsplit=1)[1]
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
try:
x = await ytdl.parse(url)
if x is None:
- return await message.reply("Failed parse URL, check logs..")
+ return await message.reply(strings("err_parse"))
img = await get_ytthumb(x.key)
caption = x.caption
markup = x.buttons
@@ -83,9 +83,10 @@ async def ytdownv2(_, message):
@app.on_callback_query(filters.regex(r"^yt_listall"))
@ratelimiter
-async def ytdl_listall_callback(_, cq: CallbackQuery):
+@use_chat_lang()
+async def ytdl_listall_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
- return await cq.answer("Not your task", True)
+ return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
media, buttons = await ytdl.listview(callback[1])
@@ -94,10 +95,11 @@ async def ytdl_listall_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^yt_extract_info"))
@ratelimiter
-async def ytdl_extractinfo_callback(_, cq: CallbackQuery):
+@use_chat_lang()
+async def ytdl_extractinfo_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
- return await cq.answer("Not your task", True)
- await cq.answer("Please Wait...")
+ return await cq.answer(strings("unauth"), True)
+ await cq.answer(strings("wait"))
callback = cq.data.split("|")
async with iYTDL(log_group_id=0, cache_path="cache", ffmpeg_location="/usr/bin/mediaextract") as ytdl:
if data := await ytdl.extract_info_from_key(callback[1]):
@@ -120,9 +122,10 @@ async def ytdl_extractinfo_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^yt_(gen|dl)"))
@ratelimiter
-async def ytdl_gendl_callback(_, cq: CallbackQuery):
+@use_chat_lang()
+async def ytdl_gendl_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
- return await cq.answer("Not your task", True)
+ return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|")
key = callback[1]
if callback[0] == "yt_gen":
@@ -170,9 +173,10 @@ async def ytdl_gendl_callback(_, cq: CallbackQuery):
@app.on_callback_query(filters.regex(r"^ytdl_scroll"))
@ratelimiter
-async def ytdl_scroll_callback(_, cq: CallbackQuery):
+@use_chat_lang()
+async def ytdl_scroll_callback(_, cq: CallbackQuery, strings):
if cq.from_user.id != cq.message.reply_to_message.from_user.id:
- return await cq.answer("Not your task", True)
+ return await cq.answer(strings("unauth"), True)
callback = cq.data.split("|")
search_key = callback[1]
page = int(callback[2])
@@ -180,13 +184,10 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery):
search = await main.VideosSearch(query).next()
i = search["result"][page]
out = f"{i['title']}"
- out += f"\nPublished {i['publishedTime']}\n"
- out += f"\nβ― Duration: {i['duration']}"
- out += f"\nβ― Views: {i['viewCount']['short']}"
- out += f"\nβ― Uploader: {i['channel']['name']}\n\n"
+ out = strings("yts_msg").format(pub=i['publishedTime'], dur=i['duration'], vi=i['viewCount']['short'], clink=i['channel']['link'], cname=i['channel']['name'])
scroll_btn = [
[
- InlineKeyboardButton("Back", callback_data=f"ytdl_scroll|{search_key}|{page-1}"),
+ InlineKeyboardButton(strings("back"), callback_data=f"ytdl_scroll|{search_key}|{page-1}"),
InlineKeyboardButton(
f"{page+1}/{len(search['result'])}",
callback_data=f"ytdl_scroll|{search_key}|{page+1}",
@@ -195,11 +196,11 @@ async def ytdl_scroll_callback(_, cq: CallbackQuery):
]
if page == 0:
if len(search["result"]) == 1:
- return await cq.answer("That's the end of list", show_alert=True)
+ return await cq.answer(strings("endlist"), show_alert=True)
scroll_btn = [[scroll_btn.pop().pop()]]
elif page == (len(search["result"]) - 1):
scroll_btn = [[scroll_btn.pop().pop(0)]]
- btn = [[InlineKeyboardButton("Download", callback_data=f"yt_gen|{i['id']}")]]
+ btn = [[InlineKeyboardButton(strings("dl_btn"), callback_data=f"yt_gen|{i['id']}")]]
btn = InlineKeyboardMarkup(scroll_btn + btn)
await cq.edit_message_media(InputMediaPhoto(await get_ytthumb(i["id"]), caption=out), reply_markup=btn)