This repository has been archived on 2024-08-21. You can view files and clone it, but cannot push or open issues or pull requests.
TelegramPoster/modules/sender.py

208 lines
7.2 KiB
Python

from datetime import datetime
import logging
from os import makedirs, path
from random import choice
from shutil import rmtree
from traceback import format_exc
from uuid import uuid4
from PIL import Image
import aiofiles
from aiohttp import ClientSession
from pyrogram.client import Client
from modules.api_client import authorize, photo_patch, photo_find, client
from modules.database import col_sent, col_submitted
from photosapi_client.errors import UnexpectedStatus
logger = logging.getLogger(__name__)
async def send_content(app: Client, http_session: ClientSession) -> None:
try:
try:
token = await authorize(http_session)
except ValueError:
await app.send_message(
app.owner,
app._("api_creds_invalid", "message"),
)
return
try:
pic = choice(
(
await photo_find(
album=app.config["posting"]["api"]["album"],
caption="queue",
page_size=app.config["posting"]["page_size"],
client=client,
)
).results
)
except (KeyError, AttributeError, TypeError):
logger.info(app._("post_empty", "console"))
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("api_queue_empty", "message"),
)
return
except (ValueError, UnexpectedStatus):
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("api_queue_error", "message"),
)
return
response = await http_session.get(
f"{app.config['posting']['api']['address']}/photos/{pic.id}",
headers={"Authorization": f"Bearer {token}"},
)
if response.status != 200:
logger.warning(
app._("post_invalid_pic", "console").format(
response.status, str(await response.json())
)
)
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_invalid_pic", "message").format(
response.status, await response.json()
),
)
tmp_dir = str(uuid4())
makedirs(path.join(app.config["locations"]["tmp"], tmp_dir), exist_ok=True)
tmp_path = path.join(tmp_dir, pic.filename)
async with aiofiles.open(
path.join(app.config["locations"]["tmp"], tmp_path), "wb"
) as out_file:
await out_file.write(await response.read())
logger.info(
f"Candidate {pic.filename} ({pic.id}) is {path.getsize(path.join(app.config['locations']['tmp'], tmp_path))} bytes big",
)
if path.getsize(path.join(app.config["locations"]["tmp"], tmp_path)) > 5242880:
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.ANTIALIAS)
if tmp_path.lower().endswith(".jpeg") or tmp_path.lower().endswith(".jpg"):
image.save(
path.join(app.config["locations"]["tmp"], tmp_path),
"JPEG",
optimize=True,
quality=50,
)
elif tmp_path.lower().endswith(".png"):
image.save(
path.join(app.config["locations"]["tmp"], tmp_path),
"PNG",
optimize=True,
compress_level=8,
)
image.close()
if path.getsize(path.join(app.config["locations"]["tmp"], tmp_path)) > 5242880:
rmtree(
path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True
)
raise BytesWarning
del response
submitted = col_submitted.find_one({"temp.file": pic.filename})
if submitted is not None and submitted["caption"] is not None:
caption = submitted["caption"].strip()
else:
caption = ""
if (
submitted is not None
and app.config["posting"]["submitted_caption"]["enabled"]
and (
(submitted["user"] not in app.admins)
or (
app.config["posting"]["submitted_caption"]["ignore_admins"] is False
)
)
):
caption = (
f"{caption}\n\n{app.config['posting']['submitted_caption']['text']}\n"
)
else:
caption = f"{caption}\n\n"
if app.config["caption"]["enabled"]:
if app.config["caption"]["link"] is not None:
caption = f"{caption}[{choice(app.config['caption']['text'])}]({app.config['caption']['link']})"
else:
caption = f"{caption}{choice(app.config['caption']['text'])}"
else:
caption = caption
try:
sent = await app.send_photo(
app.config["posting"]["channel"],
path.join(app.config["locations"]["tmp"], tmp_path),
caption=caption,
disable_notification=app.config["posting"]["silent"],
)
except Exception as exp:
logger.error(f"Could not send image {pic.filename} ({pic.id}) due to {exp}")
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_exception", "message").format(exp, format_exc()),
)
# rmtree(path.join(app.config['locations']['tmp'], tmp_dir), ignore_errors=True)
return
col_sent.insert_one(
{
"date": datetime.now(),
"image": pic.id,
"filename": pic.filename,
"channel": app.config["posting"]["channel"],
"caption": None
if (submitted is None or submitted["caption"] is None)
else submitted["caption"].strip(),
}
)
await photo_patch(id=pic.id, client=client, caption="sent")
rmtree(path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True)
logger.info(
app._("post_sent", "console").format(
pic.id,
str(app.config["posting"]["channel"]),
caption.replace("\n", "%n"),
str(app.config["posting"]["silent"]),
)
)
except Exception as exp:
logger.error(app._("post_exception", "console").format(str(exp), format_exc()))
if app.config["reports"]["error"]:
await app.send_message(
app.owner,
app._("post_exception", "message").format(exp, format_exc()),
)
try:
rmtree(
path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True
)
except:
pass