2 Commits
dev ... v0.3

Author SHA1 Message Date
32e6c4e96f Updated to 0.3 2023-07-06 15:24:46 +03:00
8c27fb7c37 Small fixes (#32)
* `bot.max_concurrent_transmissions` reduced to only 1
* Fixed using UnauthorizedClient when not needed

Co-authored-by: profitroll <vozhd.kk@gmail.com>
Reviewed-on: #32
2023-07-06 15:21:21 +03:00
21 changed files with 290 additions and 350 deletions

4
.gitignore vendored
View File

@@ -153,12 +153,8 @@ cython_debug/
#.idea/
# Custom
cache/
config.json
*.session
*.session-wal
*.session-shm
*.session-journal
venv

View File

@@ -57,7 +57,7 @@ class PyroClient(PyroClient):
self.config["bot"]["owner"]
]
self.sender_session: Union[ClientSession, None] = None
self.sender_session = ClientSession()
self.scopes_placeholders: Dict[str, int] = {
"owner": self.owner,
@@ -67,9 +67,6 @@ class PyroClient(PyroClient):
async def start(self):
await super().start()
if self.sender_session is None:
self.sender_session = ClientSession()
if self.config["reports"]["update"]:
try:
async with ClientSession(
@@ -107,8 +104,8 @@ class PyroClient(PyroClient):
logger.warning(
"Could not send startup message to bot owner. Perhaps user has not started the bot yet."
)
except Exception as exc:
logger.exception("Update check failed due to %s: %s", exc, format_exc())
except Exception as exp:
logger.exception("Update check failed due to %s: %s", exp, format_exc())
if self.config["mode"]["post"]:
if self.config["posting"]["use_interval"]:
@@ -137,16 +134,14 @@ class PyroClient(PyroClient):
)
await http_session.close()
if self.sender_session is not None:
await self.sender_session.close()
await self.sender_session.close()
await super().stop()
async def submit_media(
self, id: str, purge_caption: bool = False
self, id: str
) -> Tuple[Union[Message, None], Union[str, None]]:
db_entry = await col_submitted.find_one({"_id": ObjectId(id)})
db_entry = col_submitted.find_one({"_id": ObjectId(id)})
submission = None
if db_entry is None:
@@ -160,8 +155,8 @@ class PyroClient(PyroClient):
filepath = await self.download_media(
submission, file_name=self.config["locations"]["tmp"] + sep
)
except Exception as exc:
raise SubmissionUnavailableError() from exc
except Exception as exp:
raise SubmissionUnavailableError() from exp
elif not Path(
f"{self.config['locations']['data']}/submissions/{db_entry['temp']['uuid']}/{db_entry['temp']['file']}",
@@ -184,7 +179,7 @@ class PyroClient(PyroClient):
response = await photo_upload(
self.config["posting"]["api"]["album"],
client=client,
body=BodyPhotoUpload(
multipart_data=BodyPhotoUpload(
File(media_bytes, filepath.name, "image/jpeg")
),
ignore_duplicates=self.config["submission"]["allow_duplicates"],
@@ -195,20 +190,22 @@ class PyroClient(PyroClient):
response = await video_upload(
self.config["posting"]["api"]["album"],
client=client,
body=BodyVideoUpload(File(media_bytes, filepath.name, "video/*")),
multipart_data=BodyVideoUpload(
File(media_bytes, filepath.name, "video/*")
),
caption="queue",
)
# elif db_entry["type"] == SubmissionType.ANIMATION.value:
# response = await video_upload(
# self.config["posting"]["api"]["album"],
# client=client,
# body=BodyVideoUpload(
# multipart_data=BodyVideoUpload(
# File(media_bytes, filepath.name, "video/*")
# ),
# caption="queue",
# )
except UnexpectedStatus as exc:
raise SubmissionUnsupportedError(str(filepath)) from exc
except UnexpectedStatus as exp:
raise SubmissionUnsupportedError(str(filepath)) from exp
response_dict = (
{}
@@ -229,14 +226,10 @@ class PyroClient(PyroClient):
)
raise SubmissionDuplicatesError(str(filepath), duplicates)
db_update = (
{"$set": {"done": True, "caption": None}}
if purge_caption
else {"$set": {"done": True}}
col_submitted.find_one_and_update(
{"_id": ObjectId(id)}, {"$set": {"done": True}}
)
await col_submitted.update_one({"_id": ObjectId(id)}, db_update)
try:
if db_entry["temp"]["uuid"] is not None:
rmtree(
@@ -265,12 +258,12 @@ class PyroClient(PyroClient):
* `PyroUser`: PyroUser object
"""
if (
await col_users.find_one(
col_users.find_one(
{"id": user.id if isinstance(user, User) else user}
) # type: ignore
is None
):
await col_users.insert_one(
col_users.insert_one(
{
"id": user.id if isinstance(user, User) else user,
"locale": user.language_code if isinstance(user, User) else None,
@@ -280,7 +273,7 @@ class PyroClient(PyroClient):
}
) # type: ignore
db_record = await col_users.find_one(
db_record = col_users.find_one(
{"id": user.id if isinstance(user, User) else user}
) # type: ignore

View File

@@ -20,19 +20,19 @@ class PyroUser:
cooldown: datetime
subscription: dict
async def update_locale(self, locale: str) -> None:
await col_users.update_one({"_id": self._id}, {"$set": {"locale": locale}})
async def update_locale(self, locale: str):
col_users.update_one({"_id": self._id}, {"$set": {"locale": locale}})
async def update_cooldown(self, time: datetime = datetime.now()) -> None:
await col_users.update_one({"_id": self._id}, {"$set": {"cooldown": time}})
async def update_cooldown(self, time: datetime = datetime.now()):
col_users.update_one({"_id": self._id}, {"$set": {"cooldown": time}})
async def block(self) -> None:
"""Ban user from using command and submitting content."""
await col_users.update_one({"_id": self._id}, {"$set": {"banned": True}})
col_users.update_one({"_id": self._id}, {"$set": {"banned": True}})
async def unblock(self) -> None:
"""Allow user to use command and submit posts again."""
await col_users.update_one({"_id": self._id}, {"$set": {"banned": False}})
col_users.update_one({"_id": self._id}, {"$set": {"banned": False}})
async def is_limited(self, app: Union[PyroClient, None] = None) -> bool:
"""Check if user is on a cooldown after submitting something.
@@ -41,9 +41,11 @@ class PyroUser:
`bool`: Must be `True` if on the cooldown and `False` if not
"""
admins = (
await config_get("admins", "bot") + [await config_get("owner", "bot")]
if app is None
else app.admins
app.admins
if app is not None
else (
await config_get("admins", "bot") + [await config_get("owner", "bot")]
)
)
return (datetime.now() - self.cooldown).total_seconds() < (

View File

@@ -83,8 +83,7 @@
"address_external": "https://photos.domain.com",
"username": "",
"password": "",
"album": "",
"timeout": 15.0
"album": ""
}
},
"caption": {

View File

@@ -32,7 +32,6 @@
"sub_yes_auto": "✅ Submission automatically accepted",
"sub_no": "❌ Submission reviewed and declined",
"sub_dup": "⚠️ Submission automatically declined because database already contains this photo",
"sub_deleted": "⚠️ Submission's database record ({0}) is not available.",
"sub_blocked": "You were blocked and you can't submit media anymore.",
"sub_unblocked": "You were unblocked and you can now submit media.",
"sub_by": "\n\nSubmitted by:",

View File

@@ -31,7 +31,6 @@
"sub_yes_auto": "✅ Подання автоматично прийнято",
"sub_no": "❌ Подання розглянуто та відхилено",
"sub_dup": "⚠️ Подання автоматично відхилено через наявність цього фото в базі даних",
"sub_deleted": "⚠️ Запис подання у базі даних ({0}) недоступний.",
"sub_blocked": "Вас заблокували, ви більше не можете надсилати медіафайли.",
"sub_unblocked": "Вас розблокували, тепер ви можете надсилати медіафайли.",
"sub_by": "\n\nПредставлено:",

View File

@@ -117,14 +117,16 @@ async def authorize(custom_session: Union[ClientSession, None] = None) -> str:
unauthorized_client = Client(
sync.config_get("address", "posting", "api"),
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
timeout=sync.config_get("timeout", "posting", "api"),
follow_redirects=False,
)
login_token = login(
client=unauthorized_client,
body=BodyLoginForAccessTokenTokenPost(
form_data=BodyLoginForAccessTokenTokenPost(
grant_type="password",
scope="me albums.list albums.read albums.write photos.list photos.read photos.write videos.list videos.read videos.write",
username=sync.config_get("username", "posting", "api"),
@@ -139,10 +141,12 @@ if not isinstance(login_token, Token):
exit()
client = AuthenticatedClient(
sync.config_get("address", "posting", "api"),
token=login_token.access_token,
base_url=sync.config_get("address", "posting", "api"),
timeout=5.0,
verify_ssl=True,
raise_on_unexpected_status=True,
timeout=sync.config_get("timeout", "posting", "api"),
token=login_token.access_token,
follow_redirects=False,
)
if __name__ == "__main__":

View File

@@ -58,8 +58,8 @@ async def cli_create_user() -> None:
none = input(
"Alright. If you have email confirmation enabled - please confirm registration by using the link in your email. After that press Enter. Otherwise just press Enter."
)
except Exception as exc:
print(f"Could not create a user due to {exc}", flush=True)
except Exception as exp:
print(f"Could not create a user due to {exp}", flush=True)
print_exc()
exit()
if not args.create_album:
@@ -97,8 +97,8 @@ async def cli_create_album() -> None:
result_2 = await album_create(client=client, name=name, title=title)
# asyncio.run(create_album(name, title))
await config_set("album", name, "posting", "api")
except Exception as exc:
print(f"Could not create an album due to {exc}", flush=True)
except Exception as exp:
print(f"Could not create an album due to {exp}", flush=True)
print_exc()
exit()
print("You're done!", flush=True)

View File

@@ -1,18 +0,0 @@
"""Custom message filters"""
from pyrogram import filters
from pyrogram.types import Message
from classes.pyroclient import PyroClient
async def _mode_post_func(_, __: PyroClient, message: Message):
return __.config["mode"]["post"]
async def _mode_submit_func(_, __: PyroClient, message: Message):
return __.config["mode"]["submit"]
mode_post = filters.create(_mode_post_func)
mode_submit = filters.create(_mode_submit_func)

View File

@@ -1,9 +1,11 @@
"""Module that provides all database columns"""
from async_pymongo import AsyncClient
from libbot import sync
from pymongo import MongoClient
from ujson import loads
db_config = sync.config_get("database")
with open("config.json", "r", encoding="utf-8") as f:
db_config = loads(f.read())["database"]
f.close()
if db_config["user"] is not None and db_config["password"] is not None:
con_string = "mongodb://{0}:{1}@{2}:{3}/{4}".format(
@@ -18,9 +20,15 @@ else:
db_config["host"], db_config["port"], db_config["name"]
)
db_client = AsyncClient(con_string)
db_client = MongoClient(con_string)
db = db_client.get_database(name=db_config["name"])
collections = db.list_collection_names()
for collection in ["sent", "users", "submitted"]:
if collection not in collections:
db.create_collection(collection)
col_sent = db.get_collection("sent")
col_users = db.get_collection("users")
col_submitted = db.get_collection("submitted")

View File

@@ -77,12 +77,12 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
try:
response: File = await func_iter[1](id=media.id, client=client)
except Exception as exc:
except Exception as exp:
print_exc()
logger.error("Media is invalid: %s", exc)
logger.error("Media is invalid: %s", exp)
if app.config["reports"]["error"]:
await app.send_message(
app.owner, f"Media is invalid: {exc}"
app.owner, f"Media is invalid: {exp}"
)
return
@@ -103,11 +103,11 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
).results[0]
try:
response: File = await func[1](id=media.id, client=client)
except Exception as exc:
except Exception as exp:
print_exc()
logger.error("Media is invalid: %s", exc)
logger.error("Media is invalid: %s", exp)
if app.config["reports"]["error"]:
await app.send_message(app.owner, f"Media is invalid: {exc}")
await app.send_message(app.owner, f"Media is invalid: {exp}")
return
except (KeyError, AttributeError, TypeError, IndexError):
@@ -152,7 +152,7 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
) and func[0] is photo_random:
image = Image.open(path.join(app.config["locations"]["tmp"], tmp_path))
width, height = image.size
image = image.resize((int(width / 2), int(height / 2)), Image.LANCZOS)
image = image.resize((int(width / 2), int(height / 2)), Image.ANTIALIAS)
if tmp_path.lower().endswith(".jpeg") or tmp_path.lower().endswith(".jpg"):
image.save(
path.join(app.config["locations"]["tmp"], tmp_path),
@@ -179,7 +179,7 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
del response
submitted = await col_submitted.find_one({"temp.file": media.filename})
submitted = col_submitted.find_one({"temp.file": media.filename})
if submitted is not None and submitted["caption"] is not None:
caption = submitted["caption"].strip()
@@ -217,19 +217,19 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
caption=caption,
disable_notification=app.config["posting"]["silent"],
)
except Exception as exc:
except Exception as exp:
logger.error(
"Could not send media %s (%s) due to %s", media.filename, media.id, exc
"Could not send media %s (%s) due to %s", media.filename, media.id, exp
)
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_exception", "message").format(exc, format_exc()),
app._("post_exception", "message").format(exp, format_exc()),
)
# rmtree(path.join(app.config['locations']['tmp'], tmp_dir), ignore_errors=True)
return
await col_sent.insert_one(
col_sent.insert_one(
{
"date": datetime.now(),
"image": media.id,
@@ -253,14 +253,14 @@ async def send_content(app: PyroClient, http_session: ClientSession) -> None:
str(app.config["posting"]["silent"]),
)
except Exception as exc:
except Exception as exp:
logger.error(
"Could not send content due to %s. Traceback: %s", exc, format_exc()
"Could not send content due to %s. Traceback: %s", exp, format_exc()
)
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_exception", "message").format(exc, format_exc()),
app._("post_exception", "message").format(exp, format_exc()),
)
try:
rmtree(

View File

@@ -6,7 +6,7 @@ from classes.pyroclient import PyroClient
@Client.on_callback_query(filters.regex("nothing"))
async def callback_query_nothing(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
async def callback_query_nothing(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
await callback.answer(text=app._("nothing", "callback", locale=user.locale))
await clb.answer(text=app._("nothing", "callback", locale=user.locale))

View File

@@ -10,11 +10,11 @@ from classes.pyroclient import PyroClient
@Client.on_callback_query(filters.regex("shutdown"))
async def callback_query_nothing(app: PyroClient, callback: CallbackQuery):
if callback.from_user.id not in app.admins:
async def callback_query_nothing(app: PyroClient, clb: CallbackQuery):
if clb.from_user.id not in app.admins:
return
await callback.answer()
await clb.answer()
makedirs(await config_get("cache", "locations"), exist_ok=True)
await json_write(

View File

@@ -21,46 +21,43 @@ logger = logging.getLogger(__name__)
@Client.on_callback_query(filters.regex("sub_yes_[\s\S]*"))
async def callback_query_yes(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
async def callback_query_yes(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
db_entry = await col_submitted.find_one({"_id": ObjectId(fullcallback[2])})
db_entry = col_submitted.find_one({"_id": ObjectId(fullclb[2])})
try:
submission = await app.submit_media(
fullcallback[2],
purge_caption=("caption" not in fullcallback),
)
submission = await app.submit_media(fullclb[2])
except SubmissionUnavailableError:
await callback.answer(
await clb.answer(
text=app._("sub_msg_unavail", "callback", locale=user.locale),
show_alert=True,
)
return
except SubmissionUnsupportedError:
await callback.answer(
await clb.answer(
text=app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"]), quote=True
),
show_alert=True,
)
return
except SubmissionDuplicatesError as exc:
await callback.answer(
except SubmissionDuplicatesError as exp:
await clb.answer(
text=app._("sub_duplicates_found", "callback", locale=user.locale),
show_alert=True,
)
await callback.message.reply_text(
await clb.message.reply_text(
app._("sub_media_duplicates_list", "message", locale=user.locale).format(
"\n".join(exc.duplicates)
"\n".join(exp.duplicates)
),
quote=True,
)
logger.info(
"Submission with ID '%s' could not be accepted because of the duplicates: %s",
fullcallback[2],
str(exc.duplicates),
fullclb[2],
str(exp.duplicates),
)
return
@@ -83,8 +80,8 @@ async def callback_query_yes(app: PyroClient, callback: CallbackQuery):
),
)
await callback.answer(
text=app._("sub_yes", "callback", locale=user.locale).format(fullcallback[2]),
await clb.answer(
text=app._("sub_yes", "callback", locale=user.locale).format(fullclb[2]),
show_alert=True,
)
@@ -96,9 +93,9 @@ async def callback_query_yes(app: PyroClient, callback: CallbackQuery):
callback_data="nothing",
)
],
callback.message.reply_markup.inline_keyboard[1],
clb.message.reply_markup.inline_keyboard[1],
]
if len(callback.message.reply_markup.inline_keyboard) > 1
if len(clb.message.reply_markup.inline_keyboard) > 1
else [
[
InlineKeyboardButton(
@@ -110,44 +107,30 @@ async def callback_query_yes(app: PyroClient, callback: CallbackQuery):
)
if await config_get("send_uploaded_id", "submission"):
await callback.message.edit_caption(
f"{callback.message.caption}\n\nID: `{submission[1]}`"
await clb.message.edit_caption(
f"{clb.message.caption}\n\nID: `{submission[1]}`"
)
await callback.message.edit_reply_markup(
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info(
"Submission with ID '%s' accepted and uploaded with ID '%s'",
fullcallback[2],
submission[1],
)
logger.info(
"Submission with ID '%s' accepted and uploaded with ID '%s'",
fullcallback[2],
fullclb[2],
submission[1],
)
@Client.on_callback_query(filters.regex("sub_no_[\s\S]*"))
async def callback_query_no(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
async def callback_query_no(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
db_entry = await col_submitted.delete_one({"_id": ObjectId(fullcallback[2])})
if db_entry.deleted_count == 0:
await callback.answer(
text=app._("sub_deleted", "callback", locale=user.locale).format(
fullcallback[2]
),
show_alert=True,
)
return
db_entry = col_submitted.find_one_and_delete({"_id": ObjectId(fullclb[2])})
if (
db_entry.raw_result["temp"]["uuid"] is not None
db_entry["temp"]["uuid"] is not None
and Path(
f"{app.config['locations']['data']}/submissions/{db_entry['temp']['uuid']}"
).exists()
@@ -163,8 +146,8 @@ async def callback_query_no(app: PyroClient, callback: CallbackQuery):
submission = await app.get_messages(
db_entry["user"], db_entry["telegram"]["msg_id"]
)
except Exception as exc:
await callback.answer(
except Exception as exp:
await clb.answer(
text=app._("sub_msg_unavail", "message", locale=user.locale),
show_alert=True,
)
@@ -178,8 +161,8 @@ async def callback_query_no(app: PyroClient, callback: CallbackQuery):
),
quote=True,
)
await callback.answer(
text=app._("sub_no", "callback", locale=user.locale).format(fullcallback[2]),
await clb.answer(
text=app._("sub_no", "callback", locale=user.locale).format(fullclb[2]),
show_alert=True,
)
@@ -191,9 +174,9 @@ async def callback_query_no(app: PyroClient, callback: CallbackQuery):
callback_data="nothing",
)
],
callback.message.reply_markup.inline_keyboard[1],
clb.message.reply_markup.inline_keyboard[1],
]
if len(callback.message.reply_markup.inline_keyboard) > 1
if len(clb.message.reply_markup.inline_keyboard) > 1
else [
[
InlineKeyboardButton(
@@ -203,83 +186,81 @@ async def callback_query_no(app: PyroClient, callback: CallbackQuery):
]
]
)
await callback.message.edit_reply_markup(
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info(
"Submission with ID '%s' rejected",
fullcallback[2],
fullclb[2],
)
@Client.on_callback_query(filters.regex("sub_block_[\s\S]*"))
async def callback_query_block(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
async def callback_query_block(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
await app.send_message(
int(fullcallback[2]),
int(fullclb[2]),
app._(
"sub_blocked",
"message",
locale=(await app.find_user(int(fullcallback[2]))).locale,
locale=(await app.find_user(int(fullclb[2]))).locale,
),
)
await user.block()
await callback.answer(
text=app._("sub_block", "callback", locale=user.locale).format(fullcallback[2]),
await clb.answer(
text=app._("sub_block", "callback", locale=user.locale).format(fullclb[2]),
show_alert=True,
)
edited_markup = [
callback.message.reply_markup.inline_keyboard[0],
clb.message.reply_markup.inline_keyboard[0],
[
InlineKeyboardButton(
text=str(app._("sub_unblock", "button", locale=user.locale)),
callback_data=f"sub_unblock_{fullcallback[2]}",
callback_data=f"sub_unblock_{fullclb[2]}",
)
],
]
await callback.message.edit_reply_markup(
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info("User %s has been blocked", fullcallback[2])
logger.info("User %s has been blocked", fullclb[2])
@Client.on_callback_query(filters.regex("sub_unblock_[\s\S]*"))
async def callback_query_unblock(app: PyroClient, callback: CallbackQuery):
user = await app.find_user(callback.from_user)
fullcallback = str(callback.data).split("_")
async def callback_query_unblock(app: PyroClient, clb: CallbackQuery):
user = await app.find_user(clb.from_user)
fullclb = str(clb.data).split("_")
await app.send_message(
int(fullcallback[2]),
int(fullclb[2]),
app._(
"sub_unblocked",
"message",
locale=(await app.find_user(int(fullcallback[2]))).locale,
locale=(await app.find_user(int(fullclb[2]))).locale,
),
)
await user.unblock()
await callback.answer(
text=app._("sub_unblock", "callback", locale=user.locale).format(
fullcallback[2]
),
await clb.answer(
text=app._("sub_unblock", "callback", locale=user.locale).format(fullclb[2]),
show_alert=True,
)
edited_markup = [
callback.message.reply_markup.inline_keyboard[0],
clb.message.reply_markup.inline_keyboard[0],
[
InlineKeyboardButton(
text=str(app._("sub_block", "button", locale=user.locale)),
callback_data=f"sub_block_{fullcallback[2]}",
callback_data=f"sub_block_{fullclb[2]}",
)
],
]
await callback.message.edit_reply_markup(
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
logger.info("User %s has been unblocked", fullcallback[2])
logger.info("User %s has been unblocked", fullclb[2])

View File

@@ -15,14 +15,14 @@ from modules.utils import USERS_WITH_CONTEXT
@Client.on_message(
~filters.scheduled & filters.command(["shutdown"], prefixes=["", "/"])
)
async def cmd_kill(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
async def cmd_kill(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
return
user = await app.find_user(message.from_user)
user = await app.find_user(msg.from_user)
if len(USERS_WITH_CONTEXT) > 0:
await message.reply_text(
await msg.reply_text(
app._("shutdown_confirm", "message", locale=user.locale).format(
len(USERS_WITH_CONTEXT)
),

View File

@@ -3,32 +3,25 @@ from pyrogram.client import Client
from pyrogram.types import Message
from classes.pyroclient import PyroClient
from modules import custom_filters
@Client.on_message(
custom_filters.mode_submit
& ~filters.scheduled
& filters.command(["start"], prefixes="/")
)
async def cmd_start(app: PyroClient, message: Message):
user = await app.find_user(message.from_user)
@Client.on_message(~filters.scheduled & filters.command(["start"], prefixes="/"))
async def cmd_start(app: PyroClient, msg: Message):
user = await app.find_user(msg.from_user)
if user.banned:
return
await message.reply_text(app._("start", "message", locale=user.locale))
await msg.reply_text(app._("start", "message", locale=user.locale))
@Client.on_message(
custom_filters.mode_submit
& ~filters.scheduled
& filters.command(["rules", "help"], prefixes="/")
~filters.scheduled & filters.command(["rules", "help"], prefixes="/")
)
async def cmd_rules(app: PyroClient, message: Message):
user = await app.find_user(message.from_user)
async def cmd_rules(app: PyroClient, msg: Message):
user = await app.find_user(msg.from_user)
if user.banned:
return
await message.reply_text(app._("rules", "message", locale=user.locale))
await msg.reply_text(app._("rules", "message", locale=user.locale))

View File

@@ -37,27 +37,27 @@ logger = logging.getLogger(__name__)
@Client.on_message(~filters.scheduled & filters.command(["import"], prefixes=["", "/"]))
async def cmd_import(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
async def cmd_import(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
return
global USERS_WITH_CONTEXT
if message.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(message.from_user.id)
if msg.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(msg.from_user.id)
else:
return
user = await app.find_user(message.from_user)
user = await app.find_user(msg.from_user)
await message.reply_text(app._("import_request", "message", locale=user.locale))
await msg.reply_text(app._("import_request", "message", locale=user.locale))
answer = await listen_message(app, message.chat.id, timeout=600)
answer = await listen_message(app, msg.chat.id, timeout=600)
USERS_WITH_CONTEXT.remove(message.from_user.id)
USERS_WITH_CONTEXT.remove(msg.from_user.id)
if answer is None:
await message.reply_text(
await msg.reply_text(
app._("import_ignored", "message", locale=user.locale),
quote=True,
)
@@ -86,7 +86,7 @@ async def cmd_import(app: PyroClient, message: Message):
return
if disk_usage(getcwd())[2] < (answer.document.file_size) * 3:
await message.reply_text(
await msg.reply_text(
app._("import_too_big", "message", locale=user.locale).format(
answer.document.file_size // (2**30),
disk_usage(getcwd())[2] // (2**30),
@@ -123,16 +123,16 @@ async def cmd_import(app: PyroClient, message: Message):
for name in handle.namelist()
]
_ = await asyncio.gather(*tasks)
except Exception as exc:
except Exception as exp:
logger.error(
"Could not import '%s' due to %s: %s",
answer.document.file_name,
exc,
exp,
format_exc(),
)
await answer.reply_text(
app._("import_unpack_error", "message", locale=user.locale).format(
exc, format_exc()
exp, format_exc()
)
)
return
@@ -158,21 +158,21 @@ async def cmd_import(app: PyroClient, message: Message):
uploaded = await photo_upload(
app.config["posting"]["api"]["album"],
client=client,
body=BodyPhotoUpload(
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 exc:
except UnexpectedStatus as exp:
logger.error(
"Could not upload '%s' from '%s': %s",
filename,
Path(f"{app.config['locations']['tmp']}/{tmp_dir}"),
exc,
exp,
)
await message.reply_text(
await msg.reply_text(
app._(
"import_upload_error_other",
"message",
@@ -193,7 +193,7 @@ async def cmd_import(app: PyroClient, message: Message):
)
if len(uploaded_dict["duplicates"]) > 0:
await message.reply_text(
await msg.reply_text(
app._(
"import_upload_error_duplicate",
"message",
@@ -202,7 +202,7 @@ async def cmd_import(app: PyroClient, message: Message):
disable_notification=True,
)
else:
await message.reply_text(
await msg.reply_text(
app._(
"import_upload_error_other",
"message",
@@ -235,35 +235,33 @@ async def cmd_import(app: PyroClient, message: Message):
@Client.on_message(~filters.scheduled & filters.command(["export"], prefixes=["", "/"]))
async def cmd_export(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
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, message: Message):
if message.from_user.id not in app.admins:
async def cmd_remove(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
return
global USERS_WITH_CONTEXT
if message.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(message.from_user.id)
if msg.from_user.id not in USERS_WITH_CONTEXT:
USERS_WITH_CONTEXT.append(msg.from_user.id)
else:
return
user = await app.find_user(message.from_user)
user = await app.find_user(msg.from_user)
await message.reply_text(app._("remove_request", "message", locale=user.locale))
await msg.reply_text(app._("remove_request", "message", locale=user.locale))
answer_id = await app.listen.Message(
filters.text & ~filters.me, id=filters.user(message.from_user.id), timeout=600
)
answer_id = await listen_message(app, msg.chat.id, timeout=600)
USERS_WITH_CONTEXT.remove(message.from_user.id)
USERS_WITH_CONTEXT.remove(msg.from_user.id)
if answer_id is None:
await message.reply_text(
await msg.reply_text(
app._("remove_ignored", "message", locale=user.locale),
quote=True,
)
@@ -273,7 +271,7 @@ async def cmd_remove(app: PyroClient, message: Message):
await answer_id.reply_text(app._("remove_abort", "message", locale=user.locale))
return
await message.reply_text(
await msg.reply_text(
app._("remove_kind", "message", locale=user.locale),
reply_markup=ReplyKeyboardMarkup(
[
@@ -287,16 +285,14 @@ async def cmd_remove(app: PyroClient, message: Message):
),
)
USERS_WITH_CONTEXT.append(message.from_user.id)
USERS_WITH_CONTEXT.append(msg.from_user.id)
answer_kind = await app.listen.Message(
filters.text & ~filters.me, id=filters.user(message.from_user.id), timeout=600
)
answer_kind = await listen_message(app, msg.chat.id, timeout=600)
USERS_WITH_CONTEXT.remove(message.from_user.id)
USERS_WITH_CONTEXT.remove(msg.from_user.id)
if answer_kind is None:
await message.reply_text(
await msg.reply_text(
app._("remove_ignored", "message", locale=user.locale),
quote=True,
reply_markup=ReplyKeyboardRemove(),
@@ -355,6 +351,6 @@ async def cmd_remove(app: PyroClient, message: Message):
@Client.on_message(~filters.scheduled & filters.command(["purge"], prefixes=["", "/"]))
async def cmd_purge(app: PyroClient, message: Message):
if message.from_user.id not in app.admins:
async def cmd_purge(app: PyroClient, msg: Message):
if msg.from_user.id not in app.admins:
return

View File

@@ -4,35 +4,32 @@ from pyrogram.client import Client
from pyrogram.types import Message, User
from classes.pyroclient import PyroClient
from modules import custom_filters
@Client.on_message(
custom_filters.mode_post
& ~filters.scheduled
~filters.scheduled
& filters.chat(sync.config_get("comments", "posting"))
& filters.reply
& filters.command(["report"], prefixes=["", "/"])
)
async def command_report(app: PyroClient, message: Message):
if (
message.reply_to_message.forward_from_chat.id
!= app.config["posting"]["channel"]
):
async def command_report(app: PyroClient, msg: Message):
if msg.reply_to_message.forward_from_chat.id != app.config["posting"]["channel"]:
return
user = await app.find_user(message.from_user)
user = await app.find_user(msg.from_user)
await message.reply_text(
await msg.reply_text(
app._(
"report_sent",
"message",
locale=user.locale if message.from_user is not None else None,
locale=user.locale if msg.from_user is not None else None,
)
)
report_sent = await message.reply_to_message.forward(app.owner)
sender = message.from_user if message.from_user is not None else message.sender_chat
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

View File

@@ -13,7 +13,6 @@ from pyrogram.types import InlineKeyboardButton, InlineKeyboardMarkup, Message
from classes.enums.submission_types import SubmissionType
from classes.exceptions import SubmissionDuplicatesError, SubmissionUnsupportedError
from classes.pyroclient import PyroClient
from modules import custom_filters
from modules.database import col_submitted
from modules.utils import USERS_WITH_CONTEXT
@@ -21,126 +20,120 @@ logger = logging.getLogger(__name__)
@Client.on_message(
custom_filters.mode_submit & ~filters.scheduled & filters.private & filters.photo
~filters.scheduled & filters.private & filters.photo
| filters.video
# | filters.animation
| filters.document
)
async def get_submission(app: PyroClient, message: Message):
async def get_submission(app: PyroClient, msg: Message):
global USERS_WITH_CONTEXT
if not hasattr(message.from_user, "id"):
if not hasattr(msg.from_user, "id"):
return
if message.from_user.id in USERS_WITH_CONTEXT:
if msg.from_user.id in USERS_WITH_CONTEXT:
return
user = await app.find_user(message.from_user)
user = await app.find_user(msg.from_user)
user_owner = await app.find_user(app.owner)
try:
if user.banned:
return
await app.send_chat_action(message.chat.id, ChatAction.TYPING)
await app.send_chat_action(msg.chat.id, ChatAction.TYPING)
save_tmp = True
contents = None
if await user.is_limited():
await message.reply_text(
await msg.reply_text(
app._("sub_cooldown", "message", locale=user.locale).format(
app.config["submission"]["timeout"]
)
)
return
if message.document is not None:
if msg.document is not None:
logger.info(
"User %s is trying to submit a file of type '%s' with name '%s' and size of %s MB",
message.from_user.id,
message.document.mime_type,
message.document.file_name,
message.document.file_size / 1024 / 1024,
msg.from_user.id,
msg.document.mime_type,
msg.document.file_name,
msg.document.file_size / 1024 / 1024,
)
if message.document.mime_type not in app.config["submission"]["mime_types"]:
await message.reply_text(
if msg.document.mime_type not in app.config["submission"]["mime_types"]:
await msg.reply_text(
app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"])
),
quote=True,
)
return
if message.document.file_size > app.config["submission"]["file_size"]:
await message.reply_text(
if msg.document.file_size > app.config["submission"]["file_size"]:
await msg.reply_text(
app._("document_too_large", "message", locale=user.locale).format(
app.config["submission"]["file_size"] / 1024 / 1024
),
quote=True,
)
return
if message.document.file_size > app.config["submission"]["tmp_size"]:
if msg.document.file_size > app.config["submission"]["tmp_size"]:
save_tmp = False
contents = (
message.document.file_id,
msg.document.file_id,
SubmissionType.DOCUMENT,
) # , message.document.file_name
) # , msg.document.file_name
if message.video is not None:
if msg.video is not None:
logger.info(
"User %s is trying to submit a video with name '%s' and size of %s MB",
message.from_user.id,
message.video.file_name,
message.video.file_size / 1024 / 1024,
msg.from_user.id,
msg.video.file_name,
msg.video.file_size / 1024 / 1024,
)
if message.video.file_size > app.config["submission"]["file_size"]:
await message.reply_text(
if msg.video.file_size > app.config["submission"]["file_size"]:
await msg.reply_text(
app._("document_too_large", "message", locale=user.locale).format(
app.config["submission"]["file_size"] / 1024 / 1024
),
quote=True,
)
return
if message.video.file_size > app.config["submission"]["tmp_size"]:
if msg.video.file_size > app.config["submission"]["tmp_size"]:
save_tmp = False
contents = (
message.video.file_id,
SubmissionType.VIDEO,
) # , message.video.file_name
contents = msg.video.file_id, SubmissionType.VIDEO # , msg.video.file_name
# if message.animation is not None:
# if msg.animation is not None:
# logger.info(
# "User %s is trying to submit an animation with name '%s' and size of %s MB",
# message.from_user.id,
# message.animation.file_name,
# message.animation.file_size / 1024 / 1024,
# msg.from_user.id,
# msg.animation.file_name,
# msg.animation.file_size / 1024 / 1024,
# )
# if message.animation.file_size > app.config["submission"]["file_size"]:
# await message.reply_text(
# if msg.animation.file_size > app.config["submission"]["file_size"]:
# await msg.reply_text(
# app._("document_too_large", "message", locale=user.locale).format(
# str(app.config["submission"]["file_size"] / 1024 / 1024)
# ),
# quote=True,
# )
# return
# if message.animation.file_size > app.config["submission"]["tmp_size"]:
# if msg.animation.file_size > app.config["submission"]["tmp_size"]:
# save_tmp = False
# contents = (
# message.animation.file_id,
# msg.animation.file_id,
# SubmissionType.ANIMATION,
# ) # , message.animation.file_name
# ) # , msg.animation.file_name
if message.photo is not None:
if msg.photo is not None:
logger.info(
"User %s is trying to submit a photo with ID '%s' and size of %s MB",
message.from_user.id,
message.photo.file_id,
message.photo.file_size / 1024 / 1024,
msg.from_user.id,
msg.photo.file_id,
msg.photo.file_size / 1024 / 1024,
)
contents = (
message.photo.file_id,
SubmissionType.PHOTO,
) # , "please_generate"
contents = msg.photo.file_id, SubmissionType.PHOTO # , "please_generate"
if contents is None:
return
@@ -154,37 +147,33 @@ async def get_submission(app: PyroClient, message: Message):
exist_ok=True,
)
downloaded = await app.download_media(
message,
msg,
str(Path(f"{app.config['locations']['data']}/submissions/{tmp_id}"))
+ sep,
)
inserted = await col_submitted.insert_one(
inserted = col_submitted.insert_one(
{
"user": message.from_user.id,
"user": msg.from_user.id,
"date": datetime.now(),
"done": False,
"type": contents[1].value,
"temp": {"uuid": tmp_id, "file": path.basename(str(downloaded))},
"telegram": {"msg_id": message.id, "file_id": contents[0]},
"caption": str(message.caption)
if message.caption is not None
else None,
"telegram": {"msg_id": msg.id, "file_id": contents[0]},
"caption": str(msg.caption) if msg.caption is not None else None,
}
)
else:
inserted = await col_submitted.insert_one(
inserted = col_submitted.insert_one(
{
"user": message.from_user.id,
"user": msg.from_user.id,
"date": datetime.now(),
"done": False,
"type": contents[1].value,
"temp": {"uuid": None, "file": None},
"telegram": {"msg_id": message.id, "file_id": contents[0]},
"caption": str(message.caption)
if message.caption is not None
else None,
"telegram": {"msg_id": msg.id, "file_id": contents[0]},
"caption": str(msg.caption) if msg.caption is not None else None,
}
)
@@ -197,8 +186,8 @@ async def get_submission(app: PyroClient, message: Message):
]
]
if message.caption is not None:
caption = str(message.caption)
if msg.caption is not None:
caption = str(msg.caption)
buttons[0].append(
InlineKeyboardButton(
text=app._("sub_yes_caption", "button", locale=user_owner.locale),
@@ -216,108 +205,106 @@ async def get_submission(app: PyroClient, message: Message):
)
caption += app._("sub_by", "message", locale=user_owner.locale)
if message.from_user.first_name is not None:
caption += f" {message.from_user.first_name}"
if message.from_user.last_name is not None:
caption += f" {message.from_user.last_name}"
if message.from_user.username is not None:
caption += f" (@{message.from_user.username})"
if message.from_user.phone_number is not None:
caption += f" ({message.from_user.phone_number})"
if msg.from_user.first_name is not None:
caption += f" {msg.from_user.first_name}"
if msg.from_user.last_name is not None:
caption += f" {msg.from_user.last_name}"
if msg.from_user.username is not None:
caption += f" (@{msg.from_user.username})"
if msg.from_user.phone_number is not None:
caption += f" ({msg.from_user.phone_number})"
if (
message.from_user.id in app.admins
msg.from_user.id in app.admins
and app.config["submission"]["require_confirmation"]["admins"] is False
):
try:
submitted = await app.submit_media(str(inserted.inserted_id))
await message.reply_text(
await msg.reply_text(
app._("sub_yes_auto", "message", locale=user.locale),
disable_notification=True,
quote=True,
)
if app.config["submission"]["send_uploaded_id"]:
caption += f"\n\nID: `{submitted[1]}`"
await message.copy(
app.owner, caption=caption, disable_notification=True
)
await msg.copy(app.owner, caption=caption, disable_notification=True)
return
except SubmissionUnsupportedError:
await message.reply_text(
await msg.reply_text(
app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"]), quote=True
),
quote=True,
)
return
except SubmissionDuplicatesError as exc:
await message.reply_text(
except SubmissionDuplicatesError as exp:
await msg.reply_text(
app._(
"sub_media_duplicates_list", "message", locale=user.locale
).format("\n".join(exc.duplicates)),
).format("\n".join(exp.duplicates)),
quote=True,
)
return
except Exception as exc:
await message.reply_text(exc, quote=True)
except Exception as exp:
await msg.reply_text(format_exc(), quote=True)
return
elif (
message.from_user.id not in app.admins
msg.from_user.id not in app.admins
and app.config["submission"]["require_confirmation"]["users"] is False
):
try:
submitted = await app.submit_photo(str(inserted.inserted_id))
await message.reply_text(
await msg.reply_text(
app._("sub_yes_auto", "message", locale=user.locale),
disable_notification=True,
quote=True,
)
if app.config["submission"]["send_uploaded_id"]:
caption += f"\n\nID: `{submitted[1]}`"
await message.copy(app.owner, caption=caption)
await msg.copy(app.owner, caption=caption)
return
except SubmissionUnsupportedError:
await message.reply_text(
await msg.reply_text(
app._("mime_not_allowed", "message", locale=user.locale).format(
", ".join(app.config["submission"]["mime_types"]), quote=True
)
)
return
except SubmissionDuplicatesError as exc:
await message.reply_text(
except SubmissionDuplicatesError as exp:
await msg.reply_text(
app._("sub_dup", "message", locale=user.locale), quote=True
)
return
except Exception as exc:
except Exception as exp:
await app.send_message(
app.owner,
app._(
"sub_error_admin", "message", locale=user_owner.locale
).format(message.from_user.id, format_exc()),
).format(msg.from_user.id, format_exc()),
)
await message.reply_text("sub_error", quote=True)
await msg.reply_text("sub_error", quote=True)
return
if message.from_user.id not in app.admins:
if msg.from_user.id not in app.admins:
buttons += [
[
InlineKeyboardButton(
text=app._("sub_block", "button", locale=user_owner.locale),
callback_data=f"sub_block_{message.from_user.id}",
callback_data=f"sub_block_{msg.from_user.id}",
)
]
]
await user.update_cooldown()
if message.from_user.id != app.owner:
await message.reply_text(
if msg.from_user.id != app.owner:
await msg.reply_text(
app._("sub_sent", "message", locale=user.locale),
disable_notification=True,
quote=True,
)
await message.copy(
await msg.copy(
app.owner, caption=caption, reply_markup=InlineKeyboardMarkup(buttons)
)

View File

@@ -8,6 +8,6 @@ from classes.pyroclient import PyroClient
@Client.on_message(
~filters.scheduled & filters.private & filters.command(["remove_commands"], prefixes=["/"]) # type: ignore
)
async def command_remove_commands(app: PyroClient, message: Message):
await message.reply_text("Okay.")
async def command_remove_commands(app: PyroClient, msg: Message):
await msg.reply_text("Okay.")
await app.remove_commands(command_sets=await app.collect_commands())

View File

@@ -1,11 +1,15 @@
aiohttp~=3.10.2
async_pymongo==0.1.6
aiohttp~=3.8.4
black~=23.3.0
convopyro==0.5
pillow~=10.4.0
pykeyboard==0.1.7
pillow~=10.0.0
psutil~=5.9.4
pykeyboard==0.1.5
pymongo~=4.4.0
pyrogram==2.0.106
python_dateutil==2.8.2
pytimeparse~=1.1.8
tgcrypto==1.2.5
#uvloop==0.19.0
uvloop==0.17.0
--extra-index-url https://git.end-play.xyz/api/packages/profitroll/pypi/simple
libbot[speed,pyrogram]==3.2.3
photosapi_client==0.6.0
libbot[speed,pyrogram]==1.8
photosapi_client==0.5.0