* Config file changes
* Commands `/remove`, `/import` and `/export`

Co-authored-by: profitroll <vozhd.kk@gmail.com>
Co-authored-by: Profitroll <47523801+profitrollgame@users.noreply.github.com>
Co-authored-by: Renovate <renovate@git.end-play.xyz>
Reviewed-on: #19
This commit is contained in:
2023-04-24 13:48:22 +03:00
parent e5f80d9702
commit 853c3c7cea
37 changed files with 2121 additions and 704 deletions

View File

@@ -1,19 +1,45 @@
from os import getpid
from os import getpid, makedirs, path
from time import time
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import Message
from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
from modules.app import app
from classes.poster_client import PosterClient
from modules.app import app, users_with_context
from modules.logger import logWrite
from modules.utils import configGet, killProc, locale
from modules.scheduler import scheduler
from modules.utils import configGet, jsonSave, locale
@app.on_message(~ filters.scheduled & filters.command(["kill", "die", "reboot"], prefixes=["", "/"]))
async def cmd_kill(app: Client, msg: Message):
if msg.from_user.id == configGet("admin"):
@app.on_message(~filters.scheduled & filters.command(["shutdown"], prefixes=["", "/"]))
async def cmd_kill(app: PosterClient, msg: Message):
if msg.from_user.id in app.admins:
global users_with_context
if len(users_with_context) > 0:
await msg.reply_text(
f"There're {len(users_with_context)} unfinished users' contexts. If you turn off the bot, those will be lost. Please confirm shutdown using a button below.",
reply_markup=InlineKeyboardMarkup(
[
[
InlineKeyboardButton(
"Confirm shutdown", callback_data="shutdown"
)
]
]
),
)
return
pid = getpid()
logWrite(locale("shutdown", "console", locale=configGet("locale")).format(str(pid)))
await msg.reply_text(locale("shutdown", "message", locale=configGet("locale")).format(str(pid)))
killProc(pid)
logWrite(f"Shutting down bot with pid {pid}")
await msg.reply_text(
locale("shutdown", "message", locale=msg.from_user.language_code).format(
pid
),
)
scheduler.shutdown()
makedirs(configGet("cache", "locations"), exist_ok=True)
jsonSave(
{"timestamp": time()},
path.join(configGet("cache", "locations"), "shutdown_time"),
)
exit()

View File

@@ -1,18 +1,23 @@
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import Message
from modules.app import app
from modules.submissions import subBlocked
from modules.utils import configGet, jsonLoad, locale
from modules.utils import locale
from classes.user import PosterUser
from classes.poster_client import PosterClient
@app.on_message(~ filters.scheduled & filters.command(["start"], prefixes="/"))
async def cmd_start(app: Client, msg: Message):
if subBlocked(msg.from_user) is False:
await msg.reply_text(locale("start", "message", locale=msg.from_user.language_code))
@app.on_message(~filters.scheduled & filters.command(["start"], prefixes="/"))
async def cmd_start(app: PosterClient, msg: Message):
if PosterUser(msg.from_user.id).is_blocked() is False:
await msg.reply_text(
locale("start", "message", locale=msg.from_user.language_code)
)
@app.on_message(~ filters.scheduled & filters.command(["rules", "help"], prefixes="/"))
async def cmd_rules(app: Client, msg: Message):
if subBlocked(msg.from_user) is False:
await msg.reply_text(locale("rules", "message", locale=msg.from_user.language_code))
@app.on_message(~filters.scheduled & filters.command(["rules", "help"], prefixes="/"))
async def cmd_rules(app: PosterClient, msg: Message):
if PosterUser(msg.from_user.id).is_blocked() is False:
await msg.reply_text(
locale("rules", "message", locale=msg.from_user.language_code)
)

214
plugins/commands/photos.py Normal file
View File

@@ -0,0 +1,214 @@
import asyncio
from glob import iglob
from os import getcwd, makedirs, path, remove
from shutil import disk_usage, rmtree
from traceback import format_exc
from uuid import uuid4
from zipfile import ZipFile
from convopyro import listen_message
from pyrogram import filters
from pyrogram.types import Message
from classes.poster_client import PosterClient
from modules.api_client import remove_pic, upload_pic
from modules.app import app, users_with_context
from modules.logger import logWrite
from modules.utils import configGet, extract_and_save, locale
@app.on_message(~filters.scheduled & filters.command(["import"], prefixes=["", "/"]))
async def cmd_import(app: PosterClient, msg: Message):
if msg.from_user.id in app.admins:
global users_with_context
if msg.from_user.id not in users_with_context:
users_with_context.append(msg.from_user.id)
else:
return
await msg.reply_text(
locale("import_request", "message", locale=msg.from_user.language_code)
)
answer = await listen_message(app, msg.chat.id, timeout=600)
users_with_context.remove(msg.from_user.id)
if answer is None:
await msg.reply_text(
locale("import_ignored", "message", locale=msg.from_user.language_code),
quote=True,
)
return
if answer.text == "/cancel":
await answer.reply_text(
locale("import_abort", "message", locale=msg.from_user.language_code)
)
return
if answer.document is None:
await answer.reply_text(
locale(
"import_invalid_media",
"message",
locale=msg.from_user.language_code,
),
quote=True,
)
return
if answer.document.mime_type != "application/zip":
await answer.reply_text(
locale(
"import_invalid_mime", "message", locale=msg.from_user.language_code
),
quote=True,
)
return
if disk_usage(getcwd())[2] < (answer.document.file_size) * 3:
await msg.reply_text(
locale(
"import_too_big", "message", locale=msg.from_user.language_code
).format(
answer.document.file_size // (2**30),
disk_usage(getcwd())[2] // (2**30),
)
)
return
tmp_dir = str(uuid4())
logWrite(
f"Importing '{answer.document.file_name}' file {answer.document.file_size} bytes big (TMP ID {tmp_dir})"
)
makedirs(path.join(configGet("tmp", "locations"), tmp_dir), exist_ok=True)
tmp_path = path.join(configGet("tmp", "locations"), answer.document.file_id)
downloading = await answer.reply_text(
locale("import_downloading", "message", locale=msg.from_user.language_code),
quote=True,
)
await app.download_media(answer, file_name=tmp_path)
await downloading.edit(
locale("import_unpacking", "message", locale=msg.from_user.language_code)
)
try:
with ZipFile(tmp_path, "r") as handle:
tasks = [
extract_and_save(
handle, name, path.join(configGet("tmp", "locations"), tmp_dir)
)
for name in handle.namelist()
]
_ = await asyncio.gather(*tasks)
except Exception as exp:
logWrite(
f"Could not import '{answer.document.file_name}' due to {exp}: {format_exc}"
)
await answer.reply_text(
locale(
"import_unpack_error", "message", locale=msg.from_user.language_code
).format(exp, format_exc())
)
return
logWrite(f"Downloaded '{answer.document.file_name}' - awaiting upload")
await downloading.edit(
locale("import_uploading", "message", locale=msg.from_user.language_code)
)
remove(tmp_path)
for filename in iglob(
path.join(configGet("tmp", "locations"), tmp_dir) + "**/**", recursive=True
):
if not path.isfile(filename):
continue
# upload filename
uploaded = await upload_pic(filename)
if uploaded[0] is False:
logWrite(
f"Could not upload '{filename}' from '{path.join(configGet('tmp', 'locations'), tmp_dir)}'. Duplicates: {str(uploaded[1])}",
debug=True,
)
if len(uploaded[1]) > 0:
await msg.reply_text(
locale(
"import_upload_error_duplicate",
"message",
locale=msg.from_user.language_code,
).format(path.basename(filename)),
disable_notification=True,
)
else:
await msg.reply_text(
locale(
"import_upload_error_other",
"message",
locale=msg.from_user.language_code,
).format(path.basename(filename)),
disable_notification=True,
)
else:
logWrite(
f"Uploaded '{filename}' from '{path.join(configGet('tmp', 'locations'), tmp_dir)}' and got ID {uploaded[2]}",
debug=True,
)
await downloading.delete()
logWrite(
f"Removing '{path.join(configGet('tmp', 'locations'), tmp_dir)}' after uploading",
debug=True,
)
rmtree(path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True)
await answer.reply_text(
locale("import_finished", "message", locale=msg.from_user.language_code),
quote=True,
)
return
@app.on_message(~filters.scheduled & filters.command(["export"], prefixes=["", "/"]))
async def cmd_export(app: PosterClient, msg: Message):
if msg.from_user.id in app.admins:
pass
@app.on_message(~filters.scheduled & filters.command(["remove"], prefixes=["", "/"]))
async def cmd_remove(app: PosterClient, msg: Message):
if msg.from_user.id in app.admins:
global users_with_context
if msg.from_user.id not in users_with_context:
users_with_context.append(msg.from_user.id)
else:
return
await msg.reply_text(
locale("remove_request", "message", locale=msg.from_user.language_code)
)
answer = await listen_message(app, msg.chat.id, timeout=600)
users_with_context.remove(msg.from_user.id)
if answer is None:
await msg.reply_text(
locale("remove_ignored", "message", locale=msg.from_user.language_code),
quote=True,
)
return
if answer.text == "/cancel":
await answer.reply_text(
locale("remove_abort", "message", locale=msg.from_user.language_code)
)
return
response = await remove_pic(answer.text)
if response:
logWrite(
f"Removed '{answer.text}' by request of user {answer.from_user.id}"
)
await answer.reply_text(
locale(
"remove_success", "message", locale=msg.from_user.language_code
).format(answer.text)
)
else:
logWrite(
f"Could not remove '{answer.text}' by request of user {answer.from_user.id}"
)
await answer.reply_text(
locale(
"remove_failure", "message", locale=msg.from_user.language_code
).format(answer.text)
)
@app.on_message(~filters.scheduled & filters.command(["purge"], prefixes=["", "/"]))
async def cmd_purge(app: PosterClient, msg: Message):
if msg.from_user.id in app.admins:
pass