API usage overhaul (#27)
* `/report` command added * Updated to libbot 1.5 * Moved to [PhotosAPI_Client](https://git.end-play.xyz/profitroll/PhotosAPI_Client) v0.5.0 from using self-made API client * Video support (almost stable) * Bug fixes and improvements Co-authored-by: profitroll <vozhd.kk@gmail.com> Reviewed-on: #27
This commit is contained in:
@@ -1,45 +1,45 @@
|
||||
from os import getpid, makedirs, path
|
||||
from os import makedirs
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
|
||||
from libbot import json_write
|
||||
from pyrogram import filters
|
||||
from pyrogram.types import Message, InlineKeyboardMarkup, InlineKeyboardButton
|
||||
from pyrogram.client import Client
|
||||
from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
|
||||
|
||||
from classes.poster_client import PosterClient
|
||||
from modules.app import app, users_with_context
|
||||
from modules.logger import logWrite
|
||||
from modules.scheduler import scheduler
|
||||
from modules.utils import configGet, jsonSave, locale
|
||||
from classes.pyroclient import PyroClient
|
||||
from modules.utils import USERS_WITH_CONTEXT
|
||||
|
||||
|
||||
@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(f"Shutting down bot with pid {pid}")
|
||||
@Client.on_message(
|
||||
~filters.scheduled & filters.command(["shutdown"], prefixes=["", "/"])
|
||||
)
|
||||
async def cmd_kill(app: PyroClient, msg: Message):
|
||||
if msg.from_user.id not in app.admins:
|
||||
return
|
||||
|
||||
if len(USERS_WITH_CONTEXT) > 0:
|
||||
await msg.reply_text(
|
||||
locale("shutdown", "message", locale=msg.from_user.language_code).format(
|
||||
pid
|
||||
app._("shutdown_confirm", "message").format(len(USERS_WITH_CONTEXT)),
|
||||
reply_markup=InlineKeyboardMarkup(
|
||||
[
|
||||
[
|
||||
InlineKeyboardButton(
|
||||
app._(
|
||||
"shutdown", "button", locale=msg.from_user.language_code
|
||||
),
|
||||
callback_data="shutdown",
|
||||
)
|
||||
]
|
||||
]
|
||||
),
|
||||
)
|
||||
scheduler.shutdown()
|
||||
makedirs(configGet("cache", "locations"), exist_ok=True)
|
||||
jsonSave(
|
||||
{"timestamp": time()},
|
||||
path.join(configGet("cache", "locations"), "shutdown_time"),
|
||||
)
|
||||
exit()
|
||||
return
|
||||
|
||||
makedirs(app.config["locations"]["cache"], exist_ok=True)
|
||||
await json_write(
|
||||
{"timestamp": time()},
|
||||
Path(f"{app.config['locations']['cache']}/shutdown_time"),
|
||||
)
|
||||
|
||||
exit()
|
||||
|
@@ -1,23 +1,24 @@
|
||||
from pyrogram import filters
|
||||
from pyrogram.client import Client
|
||||
from pyrogram.types import Message
|
||||
|
||||
from modules.app import app
|
||||
from modules.utils import locale
|
||||
from classes.pyroclient import PyroClient
|
||||
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: 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)
|
||||
)
|
||||
@Client.on_message(~filters.scheduled & filters.command(["start"], prefixes="/"))
|
||||
async def cmd_start(app: PyroClient, msg: Message):
|
||||
if PosterUser(msg.from_user.id).is_blocked():
|
||||
return
|
||||
|
||||
await msg.reply_text(app._("start", "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)
|
||||
)
|
||||
@Client.on_message(
|
||||
~filters.scheduled & filters.command(["rules", "help"], prefixes="/")
|
||||
)
|
||||
async def cmd_rules(app: PyroClient, msg: Message):
|
||||
if PosterUser(msg.from_user.id).is_blocked():
|
||||
return
|
||||
|
||||
await msg.reply_text(app._("rules", "message", locale=msg.from_user.language_code))
|
||||
|
@@ -1,214 +1,303 @@
|
||||
import asyncio
|
||||
import logging
|
||||
from glob import iglob
|
||||
from io import BytesIO
|
||||
from os import getcwd, makedirs, path, remove
|
||||
from pathlib import Path
|
||||
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 photosapi_client.errors import UnexpectedStatus
|
||||
from pyrogram import filters
|
||||
from pyrogram.client import Client
|
||||
from pyrogram.types import Message
|
||||
from ujson import loads
|
||||
|
||||
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
|
||||
from classes.pyroclient import PyroClient
|
||||
from modules.api_client import (
|
||||
BodyPhotoUpload,
|
||||
File,
|
||||
client,
|
||||
photo_delete,
|
||||
photo_upload,
|
||||
)
|
||||
from modules.utils import USERS_WITH_CONTEXT, extract_and_save
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@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
|
||||
@Client.on_message(~filters.scheduled & filters.command(["import"], prefixes=["", "/"]))
|
||||
async def cmd_import(app: PyroClient, msg: Message):
|
||||
if msg.from_user.id not in app.admins:
|
||||
return
|
||||
|
||||
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(
|
||||
app._("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_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),
|
||||
app._("import_ignored", "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)
|
||||
if answer.text == "/cancel":
|
||||
await answer.reply_text(
|
||||
app._("import_abort", "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:
|
||||
return
|
||||
|
||||
if answer.document is None:
|
||||
await answer.reply_text(
|
||||
app._(
|
||||
"import_invalid_media",
|
||||
"message",
|
||||
locale=msg.from_user.language_code,
|
||||
),
|
||||
quote=True,
|
||||
)
|
||||
return
|
||||
|
||||
if answer.document.mime_type != "application/zip":
|
||||
await answer.reply_text(
|
||||
app._("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(
|
||||
app._(
|
||||
"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())
|
||||
|
||||
logging.info(
|
||||
"Importing '%s' file %s bytes big (TMP ID %s)",
|
||||
answer.document.file_name,
|
||||
answer.document.file_size,
|
||||
tmp_dir,
|
||||
)
|
||||
|
||||
makedirs(Path(f"{app.config['locations']['tmp']}/{tmp_dir}"), exist_ok=True)
|
||||
tmp_path = Path(f"{app.config['locations']['tmp']}/{answer.document.file_id}")
|
||||
|
||||
downloading = await answer.reply_text(
|
||||
app._("import_downloading", "message", locale=msg.from_user.language_code),
|
||||
quote=True,
|
||||
)
|
||||
|
||||
await app.download_media(answer, file_name=str(tmp_path))
|
||||
await downloading.edit(
|
||||
app._("import_unpacking", "message", locale=msg.from_user.language_code)
|
||||
)
|
||||
|
||||
try:
|
||||
with ZipFile(tmp_path, "r") as handle:
|
||||
tasks = [
|
||||
extract_and_save(
|
||||
handle, name, Path(f"{app.config['locations']['tmp']}/{tmp_dir}")
|
||||
)
|
||||
for name in handle.namelist()
|
||||
]
|
||||
_ = await asyncio.gather(*tasks)
|
||||
except Exception as exp:
|
||||
logger.error(
|
||||
"Could not import '%s' due to %s: %s",
|
||||
answer.document.file_name,
|
||||
exp,
|
||||
format_exc(),
|
||||
)
|
||||
await answer.reply_text(
|
||||
app._(
|
||||
"import_unpack_error", "message", locale=msg.from_user.language_code
|
||||
).format(exp, format_exc())
|
||||
)
|
||||
return
|
||||
|
||||
logger.info("Downloaded '%s' - awaiting upload", answer.document.file_name)
|
||||
|
||||
await downloading.edit(
|
||||
app._("import_uploading", "message", locale=msg.from_user.language_code)
|
||||
)
|
||||
|
||||
remove(tmp_path)
|
||||
|
||||
for filename in iglob(
|
||||
str(Path(f"{app.config['locations']['tmp']}/{tmp_dir}")) + "**/**",
|
||||
recursive=True,
|
||||
):
|
||||
if not path.isfile(filename):
|
||||
continue
|
||||
|
||||
with open(str(filename), "rb") as fh:
|
||||
photo_bytes = BytesIO(fh.read())
|
||||
|
||||
try:
|
||||
uploaded = await photo_upload(
|
||||
app.config["posting"]["api"]["album"],
|
||||
client=client,
|
||||
multipart_data=BodyPhotoUpload(
|
||||
File(photo_bytes, Path(filename).name, "image/jpeg")
|
||||
),
|
||||
ignore_duplicates=app.config["submission"]["allow_duplicates"],
|
||||
compress=False,
|
||||
caption="queue",
|
||||
)
|
||||
except UnexpectedStatus as exp:
|
||||
logger.error(
|
||||
"Could not upload '%s' from '%s': %s",
|
||||
filename,
|
||||
Path(f"{app.config['locations']['tmp']}/{tmp_dir}"),
|
||||
exp,
|
||||
)
|
||||
await msg.reply_text(
|
||||
locale("remove_ignored", "message", locale=msg.from_user.language_code),
|
||||
quote=True,
|
||||
app._(
|
||||
"import_upload_error_other",
|
||||
"message",
|
||||
locale=msg.from_user.language_code,
|
||||
).format(path.basename(filename)),
|
||||
disable_notification=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)
|
||||
continue
|
||||
|
||||
uploaded_dict = loads(uploaded.content.decode("utf-8"))
|
||||
|
||||
if "duplicates" in uploaded_dict:
|
||||
logger.warning(
|
||||
"Could not upload '%s' from '%s'. Duplicates: %s",
|
||||
filename,
|
||||
Path(f"{app.config['locations']['tmp']}/{tmp_dir}"),
|
||||
str(uploaded_dict["duplicates"]),
|
||||
)
|
||||
|
||||
if len(uploaded_dict["duplicates"]) > 0:
|
||||
await msg.reply_text(
|
||||
app._(
|
||||
"import_upload_error_duplicate",
|
||||
"message",
|
||||
locale=msg.from_user.language_code,
|
||||
).format(path.basename(filename)),
|
||||
disable_notification=True,
|
||||
)
|
||||
else:
|
||||
await msg.reply_text(
|
||||
app._(
|
||||
"import_upload_error_other",
|
||||
"message",
|
||||
locale=msg.from_user.language_code,
|
||||
).format(path.basename(filename)),
|
||||
disable_notification=True,
|
||||
)
|
||||
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)
|
||||
logger.info(
|
||||
"Uploaded '%s' from '%s' and got ID %s",
|
||||
filename,
|
||||
Path(f"{app.config['locations']['tmp']}/{tmp_dir}"),
|
||||
uploaded.parsed.id,
|
||||
)
|
||||
|
||||
await downloading.delete()
|
||||
|
||||
@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
|
||||
logger.info(
|
||||
"Removing '%s' after uploading",
|
||||
Path(f"{app.config['locations']['tmp']}/{tmp_dir}"),
|
||||
)
|
||||
rmtree(Path(f"{app.config['locations']['tmp']}/{tmp_dir}"), ignore_errors=True)
|
||||
|
||||
await answer.reply_text(
|
||||
app._("import_finished", "message", locale=msg.from_user.language_code),
|
||||
quote=True,
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
|
||||
@Client.on_message(~filters.scheduled & filters.command(["export"], prefixes=["", "/"]))
|
||||
async def cmd_export(app: PyroClient, msg: Message):
|
||||
if msg.from_user.id not in app.admins:
|
||||
return
|
||||
|
||||
|
||||
@Client.on_message(~filters.scheduled & filters.command(["remove"], prefixes=["", "/"]))
|
||||
async def cmd_remove(app: PyroClient, msg: Message):
|
||||
if msg.from_user.id not in app.admins:
|
||||
return
|
||||
|
||||
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(
|
||||
app._("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(
|
||||
app._("remove_ignored", "message", locale=msg.from_user.language_code),
|
||||
quote=True,
|
||||
)
|
||||
return
|
||||
|
||||
if answer.text == "/cancel":
|
||||
await answer.reply_text(
|
||||
app._("remove_abort", "message", locale=msg.from_user.language_code)
|
||||
)
|
||||
return
|
||||
|
||||
response = await photo_delete(id=answer.text, client=client)
|
||||
|
||||
if response:
|
||||
logger.info(
|
||||
"Removed '%s' by request of user %s", answer.text, answer.from_user.id
|
||||
)
|
||||
await answer.reply_text(
|
||||
app._(
|
||||
"remove_success", "message", locale=msg.from_user.language_code
|
||||
).format(answer.text)
|
||||
)
|
||||
else:
|
||||
logger.warning(
|
||||
"Could not remove '%s' by request of user %s",
|
||||
answer.text,
|
||||
answer.from_user.id,
|
||||
)
|
||||
await answer.reply_text(
|
||||
app._(
|
||||
"remove_failure", "message", locale=msg.from_user.language_code
|
||||
).format(answer.text)
|
||||
)
|
||||
|
||||
|
||||
@Client.on_message(~filters.scheduled & filters.command(["purge"], prefixes=["", "/"]))
|
||||
async def cmd_purge(app: PyroClient, msg: Message):
|
||||
if msg.from_user.id not in app.admins:
|
||||
return
|
||||
|
42
plugins/commands/report.py
Normal file
42
plugins/commands/report.py
Normal file
@@ -0,0 +1,42 @@
|
||||
from pyrogram.client import Client
|
||||
from pyrogram import filters
|
||||
from pyrogram.types import Message, User
|
||||
from libbot import sync
|
||||
from classes.pyroclient import PyroClient
|
||||
|
||||
|
||||
@Client.on_message(
|
||||
~filters.scheduled
|
||||
& filters.chat(sync.config_get("comments", "posting"))
|
||||
& filters.reply
|
||||
& filters.command(["report"], prefixes=["", "/"])
|
||||
)
|
||||
async def command_report(app: PyroClient, msg: Message):
|
||||
if msg.reply_to_message.forward_from_chat.id == app.config["posting"]["channel"]:
|
||||
await msg.reply_text(
|
||||
app._(
|
||||
"report_sent",
|
||||
"message",
|
||||
locale=msg.from_user.language_code
|
||||
if msg.from_user is not None
|
||||
else None,
|
||||
)
|
||||
)
|
||||
|
||||
print(msg)
|
||||
|
||||
report_sent = await msg.reply_to_message.forward(app.owner)
|
||||
sender = msg.from_user if msg.from_user is not None else msg.sender_chat
|
||||
|
||||
sender_name = (
|
||||
sender.first_name if isinstance(sender, User) else sender.title
|
||||
)
|
||||
|
||||
# ACTION NEEDED
|
||||
# Name and username are somehow None
|
||||
await report_sent.reply_text(
|
||||
app._("report_received", "message").format(
|
||||
sender_name, sender.username, sender.id
|
||||
),
|
||||
quote=True,
|
||||
)
|
Reference in New Issue
Block a user