dev #19

Merged
profitroll merged 98 commits from dev into master 2023-04-24 13:48:22 +03:00
19 changed files with 701 additions and 250 deletions
Showing only changes of commit 88692ebc85 - Show all commits

View File

@ -4,13 +4,19 @@ from typing import Any
class SubmissionUnavailableError(Exception):
pass
class SubmissionUploadError(Exception):
def __init__(self, file_path: str, status_code: int, content: Any) -> None:
self.status_code = status_code
self.content = content
super().__init__(f"Could not upload photo '{file_path}' due to HTTP {self.status_code}: {self.content}")
super().__init__(
f"Could not upload photo '{file_path}' due to HTTP {self.status_code}: {self.content}"
)
class SubmissionDuplicatesError(Exception):
def __init__(self, file_path: str, duplicates: list) -> None:
self.duplicates = duplicates
super().__init__(f"Found duplicates of a photo '{file_path}': {self.duplicates}")
super().__init__(
f"Found duplicates of a photo '{file_path}': {self.duplicates}"
)

View File

@ -11,15 +11,14 @@ from modules.logger import logWrite
from modules.utils import configGet
class PosterClient(Client):
class PosterClient(Client):
def __init__(self, name: str, **kwargs): # type: ignore
super().__init__(name, **kwargs)
self.owner = configGet("owner")
self.admins = configGet("admins")+[configGet("owner")]
self.admins = configGet("admins") + [configGet("owner")]
async def submit_photo(self, id: str) -> Union[Message, None]:
db_entry = col_submitted.find_one({"_id": ObjectId(id)})
submission = None
@ -27,35 +26,66 @@ class PosterClient(Client):
raise SubmissionUnavailableError()
else:
if db_entry["temp"]["uuid"] is not None:
if not path.exists(path.join(configGet("data", "locations"), "submissions", db_entry["temp"]["uuid"], db_entry["temp"]["file"])):
if not path.exists(
path.join(
configGet("data", "locations"),
"submissions",
db_entry["temp"]["uuid"],
db_entry["temp"]["file"],
)
):
raise SubmissionUnavailableError()
else:
filepath = path.join(configGet("data", "locations"), "submissions", db_entry["temp"]["uuid"], db_entry["temp"]["file"])
filepath = path.join(
configGet("data", "locations"),
"submissions",
db_entry["temp"]["uuid"],
db_entry["temp"]["file"],
)
try:
submission = await self.get_messages(db_entry["user"], db_entry["telegram"]["msg_id"])
submission = await self.get_messages(
db_entry["user"], db_entry["telegram"]["msg_id"]
)
except:
pass
else:
try:
submission = await self.get_messages(db_entry["user"], db_entry["telegram"]["msg_id"])
filepath = await self.download_media(submission, file_name=configGet("tmp", "locations")+sep)
submission = await self.get_messages(
db_entry["user"], db_entry["telegram"]["msg_id"]
)
filepath = await self.download_media(
submission, file_name=configGet("tmp", "locations") + sep
)
except:
raise SubmissionUnavailableError()
response = await upload_pic(str(filepath), allow_duplicates=configGet("allow_duplicates", "submission"))
response = await upload_pic(
str(filepath), allow_duplicates=configGet("allow_duplicates", "submission")
)
if len(response[1]) > 0:
raise SubmissionDuplicatesError(str(filepath), response[1])
col_submitted.find_one_and_update({"_id": ObjectId(id)}, {"$set": {"done": True}})
col_submitted.find_one_and_update(
{"_id": ObjectId(id)}, {"$set": {"done": True}}
)
try:
if db_entry["temp"]["uuid"] is not None:
rmtree(path.join(configGet("data", "locations"), "submissions", db_entry["temp"]["uuid"]), ignore_errors=True)
rmtree(
path.join(
configGet("data", "locations"),
"submissions",
db_entry["temp"]["uuid"],
),
ignore_errors=True,
)
else:
remove(str(filepath))
except (FileNotFoundError, NotADirectoryError):
logWrite(f"Could not delete '{filepath}' on submission accepted", debug=True)
logWrite(
f"Could not delete '{filepath}' on submission accepted", debug=True
)
return submission

View File

@ -3,8 +3,8 @@ from datetime import datetime
from modules.database import col_banned, col_users
from modules.utils import configGet
class PosterUser():
class PosterUser:
def __init__(self, id: int):
self.id = id
@ -37,9 +37,19 @@ class PosterUser():
db_record = col_users.find_one({"user": self.id})
if db_record is None:
return False
return True if (datetime.now() - db_record["cooldown"]).total_seconds() < configGet("timeout", "submission") else False
return (
True
if (datetime.now() - db_record["cooldown"]).total_seconds()
< configGet("timeout", "submission")
else False
)
def limit(self) -> None:
"""Restart user's cooldown. Used after post has been submitted."""
if col_users.find_one_and_update({"user": self.id}, {"$set": {"cooldown": datetime.now()}}) is None:
if (
col_users.find_one_and_update(
{"user": self.id}, {"$set": {"cooldown": datetime.now()}}
)
is None
):
col_users.insert_one({"user": self.id, "cooldown": datetime.now()})

View File

@ -21,30 +21,48 @@ from modules.logger import logWrite
from modules.utils import configGet
http_session = ClientSession(json_serialize=dumps, )
http_session = ClientSession(
json_serialize=dumps,
)
async def authorize() -> str:
makedirs(configGet("cache", "locations"), exist_ok=True)
if path.exists(configGet("cache", "locations")+sep+"api_access") is True:
async with aiofiles.open(configGet("cache", "locations")+sep+"api_access", "rb") as file:
if path.exists(configGet("cache", "locations") + sep + "api_access") is True:
async with aiofiles.open(
configGet("cache", "locations") + sep + "api_access", "rb"
) as file:
token = b64decode(await file.read()).decode("utf-8")
if (await http_session.get(configGet("address", "posting", "api")+"/users/me/", headers={"Authorization": f"Bearer {token}"})).status == 200:
if (
await http_session.get(
configGet("address", "posting", "api") + "/users/me/",
headers={"Authorization": f"Bearer {token}"},
)
).status == 200:
return token
payload = {
"grant_type": "password",
"scope": "me albums.list albums.read albums.write photos.list photos.read photos.write videos.list videos.read videos.write",
"username": configGet("username", "posting", "api"),
"password": configGet("password", "posting", "api")
"password": configGet("password", "posting", "api"),
}
response = await http_session.post(configGet("address", "posting", "api")+"/token", data=payload)
response = await http_session.post(
configGet("address", "posting", "api") + "/token", data=payload
)
if not response.ok:
logWrite(f'Incorrect API credentials! Could not login into "{configGet("address", "posting", "api")}" using login "{configGet("username", "posting", "api")}": HTTP {response.status}')
logWrite(
f'Incorrect API credentials! Could not login into "{configGet("address", "posting", "api")}" using login "{configGet("username", "posting", "api")}": HTTP {response.status}'
)
raise ValueError
async with aiofiles.open(configGet("cache", "locations")+sep+"api_access", "wb") as file:
await file.write(b64encode((await response.json())["access_token"].encode("utf-8")))
async with aiofiles.open(
configGet("cache", "locations") + sep + "api_access", "wb"
) as file:
await file.write(
b64encode((await response.json())["access_token"].encode("utf-8"))
)
return (await response.json())["access_token"]
async def random_pic(token: Union[str, None] = None) -> Tuple[str, str]:
"""Returns random image id and filename from the queue.
@ -52,19 +70,32 @@ async def random_pic(token: Union[str, None] = None) -> Tuple[str, str]:
* `Tuple[str, str]`: First value is an ID and the filename in the filesystem to be indexed.
"""
token = await authorize() if token is None else token
logWrite(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue')
resp = await http_session.get(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue', headers={"Authorization": f"Bearer {token}"})
logWrite(
f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue'
)
resp = await http_session.get(
f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue',
headers={"Authorization": f"Bearer {token}"},
)
print(await resp.json(), flush=True)
if resp.status != 200:
logWrite(f'Could not get photos from album {configGet("album", "posting", "api")}: HTTP {resp.status}')
logWrite(f'Could not get photos from "{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue" using token "{token}": HTTP {resp.status}', debug=True)
logWrite(
f'Could not get photos from album {configGet("album", "posting", "api")}: HTTP {resp.status}'
)
logWrite(
f'Could not get photos from "{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue" using token "{token}": HTTP {resp.status}',
debug=True,
)
raise ValueError
if len((await resp.json())["results"]) == 0:
raise KeyError
pic = choice((await resp.json())["results"])
return pic["id"], pic["filename"]
async def upload_pic(filepath: str, allow_duplicates: bool = False, token: Union[str, None] = None) -> Tuple[bool, list]:
async def upload_pic(
filepath: str, allow_duplicates: bool = False, token: Union[str, None] = None
) -> Tuple[bool, list]:
token = await authorize() if token is None else token
try:
pic_name = path.basename(filepath)
@ -72,32 +103,53 @@ async def upload_pic(filepath: str, allow_duplicates: bool = False, token: Union
async with aiofiles.open(filepath, "rb") as f:
file_bytes = await f.read()
formdata = FormData()
formdata.add_field('file', file_bytes, filename=pic_name, content_type='image/jpeg')
formdata.add_field(
"file", file_bytes, filename=pic_name, content_type="image/jpeg"
)
response = await http_session.post(
f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos',
params={"caption": "queue", "compress": "false", "ignore_duplicates": str(allow_duplicates).lower()},
params={
"caption": "queue",
"compress": "false",
"ignore_duplicates": str(allow_duplicates).lower(),
},
headers={"Authorization": f"Bearer {token}"},
data=formdata
data=formdata,
)
if response.status != 200 and response.status != 409:
logWrite(f"Could not upload '{filepath}' to API: HTTP {response.status} with message '{response.content}'")
raise SubmissionUploadError(str(filepath), response.status, response.content)
logWrite(
f"Could not upload '{filepath}' to API: HTTP {response.status} with message '{response.content}'"
)
raise SubmissionUploadError(
str(filepath), response.status, response.content
)
duplicates = []
if "duplicates" in (await response.json()):
for index, duplicate in enumerate((await response.json())["duplicates"]):
if (await response.json())["access_token"] is None:
duplicates.append(f'`{duplicate["id"]}`:\n{configGet("address_external", "posting", "api")}/photos/{duplicate["id"]}')
duplicates.append(
f'`{duplicate["id"]}`:\n{configGet("address_external", "posting", "api")}/photos/{duplicate["id"]}'
)
else:
duplicates.append(f'`{duplicate["id"]}`:\n{configGet("address_external", "posting", "api")}/token/photo/{(await response.json())["access_token"]}?id={index}')
duplicates.append(
f'`{duplicate["id"]}`:\n{configGet("address_external", "posting", "api")}/token/photo/{(await response.json())["access_token"]}?id={index}'
)
return True, duplicates
except Exception as exp:
print_exc()
return False, []
async def find_pic(name: str, caption: Union[str, None] = None, token: Union[str, None] = None) -> Union[dict, None]:
async def find_pic(
name: str, caption: Union[str, None] = None, token: Union[str, None] = None
) -> Union[dict, None]:
token = await authorize() if token is None else token
try:
response = await http_session.get(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos', params={"q": name, "caption": caption}, headers={"Authorization": f"Bearer {token}"})
response = await http_session.get(
f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos',
params={"q": name, "caption": caption},
headers={"Authorization": f"Bearer {token}"},
)
# logWrite(response.json())
if response.status != 200:
return None
@ -105,16 +157,23 @@ async def find_pic(name: str, caption: Union[str, None] = None, token: Union[str
return None
return (await response.json())["results"]
except Exception as exp:
logWrite(f"Could not find image with name '{name}' and caption '{caption}' due to: {exp}")
logWrite(
f"Could not find image with name '{name}' and caption '{caption}' due to: {exp}"
)
return None
async def move_pic(id: str, token: Union[str, None] = None) -> bool:
token = await authorize() if token is None else token
try:
await http_session.patch(f'{configGet("address", "posting", "api")}/photos/{id}?caption=sent', headers={"Authorization": f"Bearer {token}"})
await http_session.patch(
f'{configGet("address", "posting", "api")}/photos/{id}?caption=sent',
headers={"Authorization": f"Bearer {token}"},
)
return True
except:
return False
if __name__ == "__main__":
print(asyncio.run(authorize()))

View File

@ -1,4 +1,9 @@
from modules.utils import configGet
from classes.poster_client import PosterClient
app = PosterClient("duptsiaposter", bot_token=configGet("bot_token", "bot"), api_id=configGet("api_id", "bot"), api_hash=configGet("api_hash", "bot"))
app = PosterClient(
"duptsiaposter",
bot_token=configGet("bot_token", "bot"),
api_id=configGet("api_id", "bot"),
api_hash=configGet("api_hash", "bot"),
)

View File

@ -3,21 +3,35 @@ from classes.poster_client import PosterClient
from pyrogram.types import BotCommand, BotCommandScopeChat
from modules.utils import configGet, locale
async def register_commands(app: PosterClient) -> None:
async def register_commands(app: PosterClient) -> None:
if configGet("submit", "mode"):
# Registering user commands
for entry in listdir(configGet("locale", "locations")):
if entry.endswith(".json"):
commands_list = []
for command in configGet("commands"):
commands_list.append(BotCommand(command, locale(command, "commands", locale=entry.replace(".json", ""))))
await app.set_bot_commands(commands_list, language_code=entry.replace(".json", ""))
commands_list.append(
BotCommand(
command,
locale(
command, "commands", locale=entry.replace(".json", "")
),
)
)
await app.set_bot_commands(
commands_list, language_code=entry.replace(".json", "")
)
# Registering user commands for fallback locale
commands_list = []
for command in configGet("commands"):
commands_list.append(BotCommand(command, locale(command, "commands", locale=configGet("locale_fallback"))))
commands_list.append(
BotCommand(
command,
locale(command, "commands", locale=configGet("locale_fallback")),
)
)
await app.set_bot_commands(commands_list)
# Registering admin commands
@ -25,10 +39,19 @@ async def register_commands(app: PosterClient) -> None:
if configGet("submit", "mode"):
for command in configGet("commands"):
commands_admin_list.append(BotCommand(command, locale(command, "commands", locale=configGet("locale"))))
commands_admin_list.append(
BotCommand(
command, locale(command, "commands", locale=configGet("locale"))
)
)
for command in configGet("commands_admin"):
commands_admin_list.append(BotCommand(command, locale(command, "commands_admin", locale=configGet("locale"))))
commands_admin_list.append(
BotCommand(
command, locale(command, "commands_admin", locale=configGet("locale"))
)
)
for admin in app.admins:
await app.set_bot_commands(commands_admin_list, scope=BotCommandScopeChat(chat_id=admin))
await app.set_bot_commands(
commands_admin_list, scope=BotCommandScopeChat(chat_id=admin)
)

View File

@ -8,18 +8,16 @@ with open("config.json", "r", encoding="utf-8") as f:
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(
con_string = "mongodb://{0}:{1}@{2}:{3}/{4}".format(
db_config["user"],
db_config["password"],
db_config["host"],
db_config["port"],
db_config["name"]
db_config["name"],
)
else:
con_string = 'mongodb://{0}:{1}/{2}'.format(
db_config["host"],
db_config["port"],
db_config["name"]
con_string = "mongodb://{0}:{1}/{2}".format(
db_config["host"], db_config["port"], db_config["name"]
)
db_client = MongoClient(con_string)

View File

@ -9,15 +9,15 @@ from shutil import copyfileobj
from datetime import datetime
with open(getcwd()+path.sep+"config.json", "r", encoding='utf8') as file:
with open(getcwd() + path.sep + "config.json", "r", encoding="utf8") as file:
json_contents = loads(file.read())
log_size = json_contents["logging"]["size"]
log_folder = json_contents["logging"]["location"]
file.close()
# Check latest log size
def checkSize(debug=False) -> None:
global log_folder
if debug:
@ -29,18 +29,26 @@ def checkSize(debug=False) -> None:
makedirs(log_folder, exist_ok=True)
log = stat(path.join(log_folder, log_file))
if (log.st_size / 1024) > log_size:
with open(path.join(log_folder, log_file), 'rb') as f_in:
with gzipopen(path.join(log_folder, f'{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.log.gz'), 'wb') as f_out:
with open(path.join(log_folder, log_file), "rb") as f_in:
with gzipopen(
path.join(
log_folder,
f'{datetime.now().strftime("%d.%m.%Y_%H:%M:%S")}.log.gz',
),
"wb",
) as f_out:
copyfileobj(f_in, f_out)
print(f'Copied {path.join(log_folder, datetime.now().strftime("%d.%m.%Y_%H:%M:%S"))}.log.gz')
open(path.join(log_folder, log_file), 'w').close()
print(
f'Copied {path.join(log_folder, datetime.now().strftime("%d.%m.%Y_%H:%M:%S"))}.log.gz'
)
open(path.join(log_folder, log_file), "w").close()
except FileNotFoundError:
print(f'Log file {path.join(log_folder, log_file)} does not exist')
print(f"Log file {path.join(log_folder, log_file)} does not exist")
pass
# Append string to log
def logAppend(message, debug=False) -> None:
global log_folder
message_formatted = f'[{datetime.now().strftime("%d.%m.%Y")}] [{datetime.now().strftime("%H:%M:%S")}] {message}'
@ -51,12 +59,13 @@ def logAppend(message, debug=False) -> None:
else:
log_file = "latest.log"
log = open(path.join(log_folder, log_file), 'a')
log.write(f'{message_formatted}\n')
log = open(path.join(log_folder, log_file), "a")
log.write(f"{message_formatted}\n")
log.close()
# Print to stdout and then to log
def logWrite(message, debug=False) -> None:
# save to log file and rotation is to be done
logAppend(f'{message}', debug=debug)
logAppend(f"{message}", debug=debug)
print(f"{message}", flush=True)

View File

@ -10,10 +10,22 @@ scheduler = AsyncIOScheduler()
if configGet("post", "mode"):
if configGet("use_interval", "posting"):
scheduler.add_job(send_content, "interval", seconds=timeparse(configGet("interval", "posting")), args=[app])
scheduler.add_job(
send_content,
"interval",
seconds=timeparse(configGet("interval", "posting")),
args=[app],
)
else:
for entry in configGet("time", "posting"):
dt_obj = datetime.strptime(entry, "%H:%M")
scheduler.add_job(send_content, "cron", hour=dt_obj.hour, minute=dt_obj.minute, args=[app])
scheduler.add_job(
send_content, "cron", hour=dt_obj.hour, minute=dt_obj.minute, args=[app]
)
scheduler.add_job(register_commands, "date", run_date=datetime.now()+timedelta(seconds=10), args=[app])
scheduler.add_job(
register_commands,
"date",
run_date=datetime.now() + timedelta(seconds=10),
args=[app],
)

View File

@ -15,13 +15,14 @@ from modules.utils import configGet, locale
async def send_content(app: PosterClient) -> None:
try:
try:
token = await authorize()
except ValueError:
await app.send_message(app.owner, locale("api_creds_invalid", "message", locale=configGet("locale")))
await app.send_message(
app.owner,
locale("api_creds_invalid", "message", locale=configGet("locale")),
)
return
try:
@ -29,19 +30,37 @@ async def send_content(app: PosterClient) -> None:
except KeyError:
logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
await app.send_message(app.owner, locale("api_queue_empty", "message", locale=configGet("locale")))
await app.send_message(
app.owner,
locale("api_queue_empty", "message", locale=configGet("locale")),
)
return
except ValueError:
if configGet("error", "reports"):
await app.send_message(app.owner, locale("api_queue_error", "message", locale=configGet("locale")))
await app.send_message(
app.owner,
locale("api_queue_error", "message", locale=configGet("locale")),
)
return
response = await http_session.get(f'{configGet("address", "posting", "api")}/photos/{pic[0]}', headers={"Authorization": f"Bearer {token}"})
response = await http_session.get(
f'{configGet("address", "posting", "api")}/photos/{pic[0]}',
headers={"Authorization": f"Bearer {token}"},
)
if response.status != 200:
logWrite(locale("post_invalid_pic", "console", locale=configGet("locale")).format(response.status, str(response.json())))
logWrite(
locale(
"post_invalid_pic", "console", locale=configGet("locale")
).format(response.status, str(response.json()))
)
if configGet("error", "reports"):
await app.send_message(app.owner, locale("post_invalid_pic", "message", locale=configGet("locale")).format(response.status, response.json()))
await app.send_message(
app.owner,
locale(
"post_invalid_pic", "message", locale=configGet("locale")
).format(response.status, response.json()),
)
tmp_dir = str(uuid4())
@ -49,23 +68,40 @@ async def send_content(app: PosterClient) -> None:
tmp_path = path.join(tmp_dir, pic[1])
async with aiofiles.open(path.join(configGet("tmp", "locations"), tmp_path), 'wb') as out_file:
async with aiofiles.open(
path.join(configGet("tmp", "locations"), tmp_path), "wb"
) as out_file:
await out_file.write(await response.read())
logWrite(f'Candidate {pic[1]} ({pic[0]}) is {path.getsize(path.join(configGet("tmp", "locations"), tmp_path))} bytes big', debug=True)
logWrite(
f'Candidate {pic[1]} ({pic[0]}) is {path.getsize(path.join(configGet("tmp", "locations"), tmp_path))} bytes big',
debug=True,
)
if path.getsize(path.join(configGet("tmp", "locations"), tmp_path)) > 5242880:
image = Image.open(path.join(configGet("tmp", "locations"), tmp_path))
width, height = image.size
image = image.resize((int(width/2), int(height/2)), Image.ANTIALIAS)
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(configGet("tmp", "locations"), tmp_path), "JPEG", optimize=True, quality=50)
image.save(
path.join(configGet("tmp", "locations"), tmp_path),
"JPEG",
optimize=True,
quality=50,
)
elif tmp_path.lower().endswith(".png"):
image.save(path.join(configGet("tmp", "locations"), tmp_path), "PNG", optimize=True, compress_level=8)
image.save(
path.join(configGet("tmp", "locations"), tmp_path),
"PNG",
optimize=True,
compress_level=8,
)
image.close()
if path.getsize(path.join(configGet("tmp", "locations"), tmp_path)) > 5242880:
rmtree(path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True)
rmtree(
path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True
)
raise BytesWarning
del response
@ -77,10 +113,17 @@ async def send_content(app: PosterClient) -> None:
else:
caption = ""
if submitted is not None and configGet("enabled", "posting", "submitted_caption") and (
(submitted["user"] not in app.admins) or (configGet("ignore_admins", "posting", "submitted_caption") is False)
if (
submitted is not None
and configGet("enabled", "posting", "submitted_caption")
and (
(submitted["user"] not in app.admins)
or (configGet("ignore_admins", "posting", "submitted_caption") is False)
)
):
caption = f"{caption}\n\n{configGet('text', 'posting', 'submitted_caption')}\n"
caption = (
f"{caption}\n\n{configGet('text', 'posting', 'submitted_caption')}\n"
)
else:
caption = f"{caption}\n\n"
@ -93,11 +136,21 @@ async def send_content(app: PosterClient) -> None:
caption = caption
try:
sent = await app.send_photo(configGet("channel", "posting"), path.join(configGet("tmp", "locations"), tmp_path), caption=caption, disable_notification=configGet("silent", "posting"))
sent = await app.send_photo(
configGet("channel", "posting"),
path.join(configGet("tmp", "locations"), tmp_path),
caption=caption,
disable_notification=configGet("silent", "posting"),
)
except Exception as exp:
logWrite(f"Could not send image {pic[1]} ({pic[0]}) due to {exp}")
if configGet("error", "reports"):
await app.send_message(app.owner, locale("post_exception", "message", locale=configGet("locale")).format(exp, format_exc()))
await app.send_message(
app.owner,
locale(
"post_exception", "message", locale=configGet("locale")
).format(exp, format_exc()),
)
# rmtree(path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True)
return
@ -107,7 +160,9 @@ async def send_content(app: PosterClient) -> None:
"image": pic[0],
"filename": pic[1],
"channel": configGet("channel", "posting"),
"caption": None if (submitted is None or submitted["caption"] is None) else submitted["caption"].strip()
"caption": None
if (submitted is None or submitted["caption"] is None)
else submitted["caption"].strip(),
}
)
@ -115,13 +170,31 @@ async def send_content(app: PosterClient) -> None:
rmtree(path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True)
logWrite(locale("post_sent", "console", locale=configGet("locale")).format(pic[0], str(configGet("channel", "posting")), caption.replace("\n", "%n"), str(configGet("silent", "posting"))))
logWrite(
locale("post_sent", "console", locale=configGet("locale")).format(
pic[0],
str(configGet("channel", "posting")),
caption.replace("\n", "%n"),
str(configGet("silent", "posting")),
)
)
except Exception as exp:
logWrite(locale("post_exception", "console", locale=configGet("locale")).format(str(exp), format_exc()))
logWrite(
locale("post_exception", "console", locale=configGet("locale")).format(
str(exp), format_exc()
)
)
if configGet("error", "reports"):
await app.send_message(app.owner, locale("post_exception", "message", locale=configGet("locale")).format(exp, format_exc()))
await app.send_message(
app.owner,
locale("post_exception", "message", locale=configGet("locale")).format(
exp, format_exc()
),
)
try:
rmtree(path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True)
rmtree(
path.join(configGet("tmp", "locations"), tmp_dir), ignore_errors=True
)
except:
pass

View File

@ -13,24 +13,30 @@ from typing import Any
from modules.logger import logWrite
def jsonLoad(filename: str) -> Any:
"""Loads arg1 as json and returns its contents"""
with open(filename, "r", encoding='utf8') as file:
with open(filename, "r", encoding="utf8") as file:
try:
output = loads(file.read())
except JSONDecodeError:
logWrite(f"Could not load json file {filename}: file seems to be incorrect!\n{print_exc()}")
logWrite(
f"Could not load json file {filename}: file seems to be incorrect!\n{print_exc()}"
)
raise
except FileNotFoundError:
logWrite(f"Could not load json file {filename}: file does not seem to exist!\n{print_exc()}")
logWrite(
f"Could not load json file {filename}: file does not seem to exist!\n{print_exc()}"
)
raise
file.close()
return output
def jsonSave(contents: Any, filename: str) -> None:
"""Dumps dict/list arg1 to file arg2"""
try:
with open(filename, "w", encoding='utf8') as file:
with open(filename, "w", encoding="utf8") as file:
file.write(dumps(contents, ensure_ascii=False, indent=4))
file.close()
except Exception as exp:
@ -57,6 +63,7 @@ def configSet(key: str, value, *args: str):
jsonSave(this_dict, "config.json")
return
def configGet(key: str, *args: str):
"""Get value of the config key
Args:
@ -71,6 +78,7 @@ def configGet(key: str, *args: str):
this_key = this_key[dict_key]
return this_key[key]
def locale(key: str, *args: str, locale=configGet("locale")):
"""Get value of locale string
Args:
@ -80,17 +88,21 @@ def locale(key: str, *args: str, locale=configGet("locale")):
Returns:
* any: Value of provided locale key
"""
if (locale == None):
if locale == None:
locale = configGet("locale")
try:
this_dict = jsonLoad(f'{configGet("locale", "locations")}{sep}{locale}.json')
except FileNotFoundError:
try:
this_dict = jsonLoad(f'{configGet("locale", "locations")}{sep}{configGet("locale")}.json')
this_dict = jsonLoad(
f'{configGet("locale", "locations")}{sep}{configGet("locale")}.json'
)
except FileNotFoundError:
try:
this_dict = jsonLoad(f'{configGet("locale_fallback", "locations")}{sep}{configGet("locale")}.json')
this_dict = jsonLoad(
f'{configGet("locale_fallback", "locations")}{sep}{configGet("locale")}.json'
)
except:
return f'⚠️ Locale in config is invalid: could not get "{key}" in {str(args)} from locale "{locale}"'
@ -103,12 +115,14 @@ def locale(key: str, *args: str, locale=configGet("locale")):
except KeyError:
return f'⚠️ Locale in config is invalid: could not get "{key}" in {str(args)} from locale "{locale}"'
try:
from psutil import Process
except ModuleNotFoundError:
print(locale("deps_missing", "console", locale=configGet("locale")), flush=True)
exit()
def killProc(pid: int) -> None:
"""Kill process by its PID. Meant to be used to kill the main process of bot itself.
@ -117,6 +131,7 @@ def killProc(pid: int) -> None:
"""
if osname == "posix":
from signal import SIGKILL
kill(pid, SIGKILL)
else:
Process(pid).kill()

View File

@ -4,8 +4,9 @@ from pyrogram.types import CallbackQuery
from classes.poster_client import PosterClient
from modules.utils import locale
# Callback empty ===============================================================================================================
@app.on_callback_query(filters.regex("nothing"))
async def callback_query_nothing(app: PosterClient, clb: CallbackQuery):
await clb.answer(text=locale("nothing", "callback", locale=clb.from_user.language_code))
# ==============================================================================================================================
await clb.answer(
text=locale("nothing", "callback", locale=clb.from_user.language_code)
)

View File

@ -1,4 +1,3 @@
from os import path
from shutil import rmtree
from pyrogram import filters
@ -15,7 +14,6 @@ from bson import ObjectId
@app.on_callback_query(filters.regex("sub_yes_[\s\S]*"))
async def callback_query_yes(app: PosterClient, clb: CallbackQuery):
fullclb = str(clb.data).split("_")
user_locale = clb.from_user.language_code
@ -24,22 +22,60 @@ async def callback_query_yes(app: PosterClient, clb: CallbackQuery):
try:
submission = await app.submit_photo(fullclb[2])
except SubmissionUnavailableError:
await clb.answer(text=locale("sub_msg_unavail", "callback", locale=user_locale), show_alert=True)
await clb.answer(
text=locale("sub_msg_unavail", "callback", locale=user_locale),
show_alert=True,
)
return
except SubmissionDuplicatesError as exp:
await clb.answer(text=locale("sub_duplicates_found", "callback", locale=user_locale), show_alert=True)
await clb.message.reply_text(locale("sub_media_duplicates_list", "message", locale=user_locale).format("\n".join(exp.duplicates)), quote=True)
await clb.answer(
text=locale("sub_duplicates_found", "callback", locale=user_locale),
show_alert=True,
)
await clb.message.reply_text(
locale("sub_media_duplicates_list", "message", locale=user_locale).format(
"\n".join(exp.duplicates)
),
quote=True,
)
return
if submission is not None:
await submission.reply_text(locale("sub_yes", "message", locale=submission.from_user.language_code), quote=True)
await submission.reply_text(
locale("sub_yes", "message", locale=submission.from_user.language_code),
quote=True,
)
elif db_entry is not None:
await app.send_message(db_entry["user"], locale("sub_yes", "message"))
await clb.answer(text=locale("sub_yes", "callback", locale=user_locale).format(fullclb[2]), show_alert=True)
await clb.answer(
text=locale("sub_yes", "callback", locale=user_locale).format(fullclb[2]),
show_alert=True,
)
edited_markup = [[InlineKeyboardButton(text=str(locale("accepted", "button", locale=user_locale)), callback_data="nothing")], clb.message.reply_markup.inline_keyboard[1]] if len(clb.message.reply_markup.inline_keyboard) > 1 else [[InlineKeyboardButton(text=str(locale("accepted", "button", locale=user_locale)), callback_data="nothing")]]
await clb.message.edit_reply_markup(reply_markup=InlineKeyboardMarkup(edited_markup))
edited_markup = (
[
[
InlineKeyboardButton(
text=str(locale("accepted", "button", locale=user_locale)),
callback_data="nothing",
)
],
clb.message.reply_markup.inline_keyboard[1],
]
if len(clb.message.reply_markup.inline_keyboard) > 1
else [
[
InlineKeyboardButton(
text=str(locale("accepted", "button", locale=user_locale)),
callback_data="nothing",
)
]
]
)
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
# try:
# if configGet("api_based", "mode") is True:
@ -68,48 +104,120 @@ async def callback_query_yes(app: PosterClient, clb: CallbackQuery):
@app.on_callback_query(filters.regex("sub_no_[\s\S]*"))
async def callback_query_no(app: PosterClient, clb: CallbackQuery):
fullclb = str(clb.data).split("_")
user_locale = clb.from_user.language_code
db_entry = col_submitted.find_one_and_delete({"_id": ObjectId(fullclb[2])})
if db_entry["temp"]["uuid"] is not None:
if path.exists(path.join(configGet("data", "locations"), "submissions", db_entry["temp"]["uuid"])):
rmtree(path.join(configGet("data", "locations"), "submissions", db_entry["temp"]["uuid"]), ignore_errors=True)
if path.exists(
path.join(
configGet("data", "locations"), "submissions", db_entry["temp"]["uuid"]
)
):
rmtree(
path.join(
configGet("data", "locations"),
"submissions",
db_entry["temp"]["uuid"],
),
ignore_errors=True,
)
try:
submission = await app.get_messages(db_entry["user"], db_entry["telegram"]["msg_id"])
submission = await app.get_messages(
db_entry["user"], db_entry["telegram"]["msg_id"]
)
except:
await clb.answer(text=locale("sub_msg_unavail", "message", locale=user_locale), show_alert=True)
await clb.answer(
text=locale("sub_msg_unavail", "message", locale=user_locale),
show_alert=True,
)
return
await submission.reply_text(locale("sub_no", "message", locale=submission.from_user.language_code), quote=True)
await clb.answer(text=locale("sub_no", "callback", locale=user_locale).format(fullclb[2]), show_alert=True)
await submission.reply_text(
locale("sub_no", "message", locale=submission.from_user.language_code),
quote=True,
)
await clb.answer(
text=locale("sub_no", "callback", locale=user_locale).format(fullclb[2]),
show_alert=True,
)
edited_markup = [[InlineKeyboardButton(text=str(locale("declined", "button", locale=user_locale)), callback_data="nothing")], clb.message.reply_markup.inline_keyboard[1]] if len(clb.message.reply_markup.inline_keyboard) > 1 else [[InlineKeyboardButton(text=str(locale("declined", "button", locale=user_locale)), callback_data="nothing")]]
await clb.message.edit_reply_markup(reply_markup=InlineKeyboardMarkup(edited_markup))
edited_markup = (
[
[
InlineKeyboardButton(
text=str(locale("declined", "button", locale=user_locale)),
callback_data="nothing",
)
],
clb.message.reply_markup.inline_keyboard[1],
]
if len(clb.message.reply_markup.inline_keyboard) > 1
else [
[
InlineKeyboardButton(
text=str(locale("declined", "button", locale=user_locale)),
callback_data="nothing",
)
]
]
)
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
@app.on_callback_query(filters.regex("sub_block_[\s\S]*"))
async def callback_query_block(app: PosterClient, clb: CallbackQuery):
fullclb = str(clb.data).split("_")
user_locale = clb.from_user.language_code
await app.send_message(int(fullclb[2]), locale("sub_blocked", "message", locale=configGet("locale")))
await app.send_message(
int(fullclb[2]), locale("sub_blocked", "message", locale=configGet("locale"))
)
PosterUser(int(fullclb[2])).block()
await clb.answer(text=locale("sub_block", "callback", locale=user_locale).format(fullclb[2]), show_alert=True)
await clb.answer(
text=locale("sub_block", "callback", locale=user_locale).format(fullclb[2]),
show_alert=True,
)
edited_markup = [clb.message.reply_markup.inline_keyboard[0], [InlineKeyboardButton(text=str(locale("sub_unblock", "button", locale=user_locale)), callback_data=f"sub_unblock_{fullclb[2]}")]]
await clb.message.edit_reply_markup(reply_markup=InlineKeyboardMarkup(edited_markup))
edited_markup = [
clb.message.reply_markup.inline_keyboard[0],
[
InlineKeyboardButton(
text=str(locale("sub_unblock", "button", locale=user_locale)),
callback_data=f"sub_unblock_{fullclb[2]}",
)
],
]
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)
@app.on_callback_query(filters.regex("sub_unblock_[\s\S]*"))
async def callback_query_unblock(app: PosterClient, clb: CallbackQuery):
fullclb = str(clb.data).split("_")
user_locale = clb.from_user.language_code
await app.send_message(int(fullclb[2]), locale("sub_unblocked", "message", locale=configGet("locale")))
await app.send_message(
int(fullclb[2]), locale("sub_unblocked", "message", locale=configGet("locale"))
)
PosterUser(int(fullclb[2])).unblock()
await clb.answer(text=locale("sub_unblock", "callback", locale=user_locale).format(fullclb[2]), show_alert=True)
await clb.answer(
text=locale("sub_unblock", "callback", locale=user_locale).format(fullclb[2]),
show_alert=True,
)
edited_markup = [clb.message.reply_markup.inline_keyboard[0], [InlineKeyboardButton(text=str(locale("sub_block", "button", locale=user_locale)), callback_data=f"sub_block_{fullclb[2]}")]]
await clb.message.edit_reply_markup(reply_markup=InlineKeyboardMarkup(edited_markup))
edited_markup = [
clb.message.reply_markup.inline_keyboard[0],
[
InlineKeyboardButton(
text=str(locale("sub_block", "button", locale=user_locale)),
callback_data=f"sub_block_{fullclb[2]}",
)
],
]
await clb.message.edit_reply_markup(
reply_markup=InlineKeyboardMarkup(edited_markup)
)

View File

@ -9,11 +9,16 @@ from modules.logger import logWrite
from modules.utils import configGet, killProc, locale
@app.on_message(~ filters.scheduled & filters.command(["kill", "die", "reboot"], prefixes=["", "/"]))
@app.on_message(
~filters.scheduled & filters.command(["kill", "die", "reboot"], prefixes=["", "/"])
)
async def cmd_kill(app: PosterClient, msg: Message):
if msg.from_user.id in app.admins:
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)))
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)

View File

@ -7,12 +7,17 @@ from classes.user import PosterUser
from classes.poster_client import PosterClient
@app.on_message(~ filters.scheduled & filters.command(["start"], prefixes="/"))
@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))
await msg.reply_text(
locale("start", "message", locale=msg.from_user.language_code)
)
@app.on_message(~ filters.scheduled & filters.command(["rules", "help"], prefixes="/"))
@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))
await msg.reply_text(
locale("rules", "message", locale=msg.from_user.language_code)
)

View File

@ -5,29 +5,25 @@ from classes.poster_client import PosterClient
from modules.app import app
@app.on_message(~ filters.scheduled & filters.command(["import"], prefixes=["", "/"]))
@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:
pass
@app.on_message(~ filters.scheduled & filters.command(["export"], prefixes=["", "/"]))
@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=["", "/"]))
@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:
pass
@app.on_message(~ filters.scheduled & filters.command(["purge"], prefixes=["", "/"]))
@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

View File

@ -17,12 +17,15 @@ from modules.utils import configGet, locale
from classes.enums.submission_types import SubmissionType
@app.on_message(~filters.scheduled & filters.private & filters.photo | filters.video | filters.animation | filters.document)
@app.on_message(
~filters.scheduled & filters.private & filters.photo
| filters.video
| filters.animation
| filters.document
)
async def get_submission(app: PosterClient, msg: Message):
try:
if col_banned.find_one( {"user": msg.from_user.id} ) is not None:
if col_banned.find_one({"user": msg.from_user.id}) is not None:
return
await app.send_chat_action(msg.chat.id, ChatAction.TYPING)
@ -32,68 +35,94 @@ async def get_submission(app: PosterClient, msg: Message):
contents = None
if PosterUser(msg.from_user.id).is_limited():
await msg.reply_text(locale("sub_cooldown", "message", locale=user_locale).format(str(configGet("timeout", "submission"))))
await msg.reply_text(
locale("sub_cooldown", "message", locale=user_locale).format(
str(configGet("timeout", "submission"))
)
)
return
if msg.document is not None:
if msg.document.mime_type not in configGet("mime_types", "submission"):
await msg.reply_text(locale("mime_not_allowed", "message", locale=user_locale), quote=True)
await msg.reply_text(
locale("mime_not_allowed", "message", locale=user_locale),
quote=True,
)
return
if msg.document.file_size > configGet("file_size", "submission"):
await msg.reply_text(locale("document_too_large", "message", locale=user_locale).format(str(configGet("file_size", "submission")/1024/1024)), quote=True)
await msg.reply_text(
locale("document_too_large", "message", locale=user_locale).format(
str(configGet("file_size", "submission") / 1024 / 1024)
),
quote=True,
)
return
if msg.document.file_size > configGet("tmp_size", "submission"):
save_tmp = False
contents = msg.document.file_id, SubmissionType.DOCUMENT #, msg.document.file_name
contents = (
msg.document.file_id,
SubmissionType.DOCUMENT,
) # , msg.document.file_name
if msg.video is not None:
if msg.video.file_size > configGet("file_size", "submission"):
await msg.reply_text(locale("document_too_large", "message", locale=user_locale).format(str(configGet("file_size", "submission")/1024/1024)), quote=True)
await msg.reply_text(
locale("document_too_large", "message", locale=user_locale).format(
str(configGet("file_size", "submission") / 1024 / 1024)
),
quote=True,
)
return
if msg.video.file_size > configGet("tmp_size", "submission"):
save_tmp = False
contents = msg.video.file_id, SubmissionType.VIDEO #, msg.video.file_name
contents = msg.video.file_id, SubmissionType.VIDEO # , msg.video.file_name
if msg.animation is not None:
if msg.animation.file_size > configGet("file_size", "submission"):
await msg.reply_text(locale("document_too_large", "message", locale=user_locale).format(str(configGet("file_size", "submission")/1024/1024)), quote=True)
await msg.reply_text(
locale("document_too_large", "message", locale=user_locale).format(
str(configGet("file_size", "submission") / 1024 / 1024)
),
quote=True,
)
return
if msg.animation.file_size > configGet("tmp_size", "submission"):
save_tmp = False
contents = msg.animation.file_id, SubmissionType.ANIMATION #, msg.animation.file_name
contents = (
msg.animation.file_id,
SubmissionType.ANIMATION,
) # , msg.animation.file_name
if msg.photo is not None:
contents = msg.photo.file_id, SubmissionType.PHOTO #, "please_generate"
contents = msg.photo.file_id, SubmissionType.PHOTO # , "please_generate"
if save_tmp is not None:
if contents is None:
return
tmp_id = str(uuid4())
# filename = tmp_id if contents[1] == "please_generate" else contents[1]
makedirs(path.join(configGet("data", "locations"), "submissions", tmp_id), exist_ok=True)
downloaded = await app.download_media(msg, path.join(configGet("data", "locations"), "submissions", tmp_id)+sep)
makedirs(
path.join(configGet("data", "locations"), "submissions", tmp_id),
exist_ok=True,
)
downloaded = await app.download_media(
msg,
path.join(configGet("data", "locations"), "submissions", tmp_id) + sep,
)
inserted = col_submitted.insert_one(
{
"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": msg.id,
"file_id": contents[0]
},
"caption": str(msg.caption) if msg.caption is not None else None
"temp": {"uuid": tmp_id, "file": path.basename(str(downloaded))},
"telegram": {"msg_id": msg.id, "file_id": contents[0]},
"caption": str(msg.caption) if msg.caption is not None else None,
}
)
else:
if contents is None:
return
@ -103,36 +132,44 @@ async def get_submission(app: PosterClient, msg: Message):
"date": datetime.now(),
"done": False,
"type": contents[1].value,
"temp": {
"uuid": None,
"file": None
},
"telegram": {
"msg_id": msg.id,
"file_id": contents[0]
},
"caption": str(msg.caption) if msg.caption is not None else None
"temp": {"uuid": None, "file": None},
"telegram": {"msg_id": msg.id, "file_id": contents[0]},
"caption": str(msg.caption) if msg.caption is not None else None,
}
)
buttons = [
[
InlineKeyboardButton(text=locale("sub_yes", "button", locale=configGet("locale")), callback_data=f"sub_yes_{str(inserted.inserted_id)}")
InlineKeyboardButton(
text=locale("sub_yes", "button", locale=configGet("locale")),
callback_data=f"sub_yes_{str(inserted.inserted_id)}",
)
]
]
if msg.caption is not None:
caption = str(msg.caption)
buttons[0].append(
InlineKeyboardButton(text=locale("sub_yes_caption", "button", locale=configGet("locale")), callback_data=f"sub_yes_{str(inserted.inserted_id)}_caption")
InlineKeyboardButton(
text=locale(
"sub_yes_caption", "button", locale=configGet("locale")
),
callback_data=f"sub_yes_{str(inserted.inserted_id)}_caption",
)
)
buttons[0].append(
InlineKeyboardButton(text=locale("sub_no", "button", locale=configGet("locale")), callback_data=f"sub_no_{str(inserted.inserted_id)}")
InlineKeyboardButton(
text=locale("sub_no", "button", locale=configGet("locale")),
callback_data=f"sub_no_{str(inserted.inserted_id)}",
)
)
else:
caption = ""
buttons[0].append(
InlineKeyboardButton(text=locale("sub_no", "button", locale=configGet("locale")), callback_data=f"sub_no_{str(inserted.inserted_id)}")
InlineKeyboardButton(
text=locale("sub_no", "button", locale=configGet("locale")),
callback_data=f"sub_no_{str(inserted.inserted_id)}",
)
)
caption += locale("sub_by", "message", locale=locale(configGet("locale")))
@ -146,45 +183,80 @@ async def get_submission(app: PosterClient, msg: Message):
if msg.from_user.phone_number is not None:
caption += f" ({msg.from_user.phone_number})"
if msg.from_user.id in app.admins and configGet("admins", "submission", "require_confirmation") is False:
if (
msg.from_user.id in app.admins
and configGet("admins", "submission", "require_confirmation") is False
):
try:
await app.submit_photo(str(inserted.inserted_id))
await msg.reply_text(locale("sub_yes_auto", "message", locale=user_locale), disable_notification=True, quote=True)
await msg.reply_text(
locale("sub_yes_auto", "message", locale=user_locale),
disable_notification=True,
quote=True,
)
await msg.copy(app.owner, caption=caption, disable_notification=True)
return
except SubmissionDuplicatesError as exp:
await msg.reply_text(locale("sub_media_duplicates_list", "message", locale=user_locale).format("\n".join(exp.duplicates)), quote=True)
await msg.reply_text(
locale(
"sub_media_duplicates_list", "message", locale=user_locale
).format("\n".join(exp.duplicates)),
quote=True,
)
return
except Exception as exp:
await msg.reply_text(format_exc(), quote=True)
return
elif msg.from_user.id not in app.admins and configGet("users", "submission", "require_confirmation") is False:
elif (
msg.from_user.id not in app.admins
and configGet("users", "submission", "require_confirmation") is False
):
try:
await app.submit_photo(str(inserted.inserted_id))
await msg.reply_text(locale("sub_yes_auto", "message", locale=user_locale), disable_notification=True, quote=True)
await msg.reply_text(
locale("sub_yes_auto", "message", locale=user_locale),
disable_notification=True,
quote=True,
)
await msg.copy(app.owner, caption=caption)
return
except SubmissionDuplicatesError as exp:
await msg.reply_text(locale("sub_dup", "message", locale=user_locale), quote=True)
await msg.reply_text(
locale("sub_dup", "message", locale=user_locale), quote=True
)
return
except Exception as exp:
await app.send_message(app.owner, locale("sub_error_admin", "message").format(msg.from_user.id, format_exc()))
await app.send_message(
app.owner,
locale("sub_error_admin", "message").format(
msg.from_user.id, format_exc()
),
)
await msg.reply_text("sub_error", quote=True)
return
if msg.from_user.id not in app.admins:
buttons += [
[
InlineKeyboardButton(text=locale("sub_block", "button", locale=configGet("locale")), callback_data=f"sub_block_{msg.from_user.id}")
InlineKeyboardButton(
text=locale("sub_block", "button", locale=configGet("locale")),
callback_data=f"sub_block_{msg.from_user.id}",
)
]
]
PosterUser(msg.from_user.id).limit()
if msg.from_user.id != app.owner:
await msg.reply_text(locale("sub_sent", "message", locale=user_locale), disable_notification=True, quote=True)
await msg.reply_text(
locale("sub_sent", "message", locale=user_locale),
disable_notification=True,
quote=True,
)
await msg.copy(app.owner, caption=caption, reply_markup=InlineKeyboardMarkup(buttons))
await msg.copy(
app.owner, caption=caption, reply_markup=InlineKeyboardMarkup(buttons)
)
except AttributeError:
logWrite(f"from_user in function get_submission does not seem to contain id")

View File

@ -9,8 +9,8 @@ from modules.utils import configGet, jsonLoad, jsonSave, killProc, locale
# Args =====================================================================================================================================
parser = ArgumentParser(
prog = "Telegram Poster",
description = "Bot for posting some of your stuff and also receiving submissions."
prog="Telegram Poster",
description="Bot for posting some of your stuff and also receiving submissions.",
)
parser.add_argument("-m", "--move-sent", action="store_true")
@ -24,11 +24,22 @@ args = parser.parse_args()
if args.move_sent:
for entry in jsonLoad(configGet("index", "locations"))["sent"]:
try:
move(configGet("queue", "locations")+sep+entry, configGet("sent", "locations")+sep+entry)
move(
configGet("queue", "locations") + sep + entry,
configGet("sent", "locations") + sep + entry,
)
except FileNotFoundError:
logWrite(locale("move_sent_doesnt_exist", "console", locale=configGet("locale")).format(entry))
logWrite(
locale(
"move_sent_doesnt_exist", "console", locale=configGet("locale")
).format(entry)
)
except Exception as exp:
logWrite(locale("move_sent_doesnt_exception", "console", locale=configGet("locale")).format(entry, exp))
logWrite(
locale(
"move_sent_doesnt_exception", "console", locale=configGet("locale")
).format(entry, exp)
)
logWrite(locale("move_sent_completed", "console", locale=configGet("locale")))
if args.cleanup:
@ -37,15 +48,19 @@ if args.cleanup:
for entry in index["sent"]:
try:
try:
remove(configGet("queue", "locations")+sep+entry)
remove(configGet("queue", "locations") + sep + entry)
except FileNotFoundError:
pass
try:
remove(configGet("sent", "locations")+sep+entry)
remove(configGet("sent", "locations") + sep + entry)
except FileNotFoundError:
pass
except Exception as exp:
logWrite(locale("cleanup_exception", "console", locale=configGet("locale")).format(entry, exp))
logWrite(
locale(
"cleanup_exception", "console", locale=configGet("locale")
).format(entry, exp)
)
jsonSave(index, jsonLoad(configGet("index", "locations")))
logWrite(locale("cleanup_completed", "console", locale=configGet("locale")))
else:
@ -56,14 +71,18 @@ if args.cleanup_index:
index = jsonLoad(configGet("index", "locations"))
index["sent"] = []
jsonSave(index, jsonLoad(configGet("index", "locations")))
logWrite(locale("cleanup_index_completed", "console", locale=configGet("locale")))
logWrite(
locale("cleanup_index_completed", "console", locale=configGet("locale"))
)
else:
logWrite(locale("cleanup_index_unathorized", "console", locale=configGet("locale")))
logWrite(
locale("cleanup_index_unathorized", "console", locale=configGet("locale"))
)
if args.norun:
logWrite(locale("passed_norun", "console", locale=configGet("locale_log")))
exit()
#===========================================================================================================================================
# ===========================================================================================================================================
# Import ===================================================================================================================================
@ -73,7 +92,7 @@ try:
except ModuleNotFoundError:
print(locale("deps_missing", "console", locale=configGet("locale")), flush=True)
exit()
#===========================================================================================================================================
# ===========================================================================================================================================
pid = getpid()
@ -125,7 +144,7 @@ if configGet("submit", "mode"):
if configGet("api_based", "mode"):
from modules.api_client import authorize
#===========================================================================================================================================
# ===========================================================================================================================================
# Work in progress
# Handle new forwards
@ -168,25 +187,30 @@ if configGet("api_based", "mode"):
# asyncio.run(main())
if __name__ == "__main__":
logWrite(locale("startup", "console", locale=configGet("locale")).format(str(pid)))
app.start()
if configGet("startup", "reports"):
app.send_message(app.owner, locale("startup", "message", locale=configGet("locale")).format(str(pid)))
app.send_message(
app.owner,
locale("startup", "message", locale=configGet("locale")).format(str(pid)),
)
if configGet("post", "mode"):
scheduler.start()
#if configGet("api_based", "mode"):
# if configGet("api_based", "mode"):
# token = await authorize()
# if len(get(f'{configGet("address", "posting", "api")}/albums?q={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"}).json()["results"]) == 0:
# post(f'{configGet("address", "posting", "api")}/albums?name={configGet("queue", "posting", "api", "albums")}&title={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"})
idle()
app.send_message(app.owner, locale("shutdown", "message", locale=configGet("locale")).format(str(pid)))
app.send_message(
app.owner,
locale("shutdown", "message", locale=configGet("locale")).format(str(pid)),
)
logWrite(locale("shutdown", "console", locale=configGet("locale")).format(str(pid)))
killProc(pid)