API usage overhaul #27
@ -8,11 +8,13 @@ from shutil import rmtree
|
|||||||
from time import time
|
from time import time
|
||||||
from traceback import format_exc
|
from traceback import format_exc
|
||||||
from typing import List, Tuple, Union
|
from typing import List, Tuple, Union
|
||||||
|
import aiofiles
|
||||||
|
|
||||||
import pyrogram
|
import pyrogram
|
||||||
from aiohttp import ClientSession
|
from aiohttp import ClientSession
|
||||||
from bson import ObjectId
|
from bson import ObjectId
|
||||||
from dateutil.relativedelta import relativedelta
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from classes.enums.submission_types import SubmissionType
|
||||||
from libbot import json_read, json_write
|
from libbot import json_read, json_write
|
||||||
from libbot.i18n import BotLocale
|
from libbot.i18n import BotLocale
|
||||||
from libbot.i18n.sync import _
|
from libbot.i18n.sync import _
|
||||||
@ -43,10 +45,14 @@ from classes.exceptions import (
|
|||||||
)
|
)
|
||||||
from classes.pyrocommand import PyroCommand
|
from classes.pyrocommand import PyroCommand
|
||||||
from modules.api_client import (
|
from modules.api_client import (
|
||||||
BodyPhotoUploadAlbumsAlbumPhotosPost,
|
BodyPhotoUpload,
|
||||||
|
BodyVideoUpload,
|
||||||
File,
|
File,
|
||||||
|
Photo,
|
||||||
|
Video,
|
||||||
client,
|
client,
|
||||||
photo_upload,
|
photo_upload,
|
||||||
|
video_upload,
|
||||||
)
|
)
|
||||||
from modules.database import col_submitted
|
from modules.database import col_submitted
|
||||||
from modules.http_client import http_session
|
from modules.http_client import http_session
|
||||||
@ -398,7 +404,7 @@ class PyroClient(Client):
|
|||||||
language_code=command_set.language_code,
|
language_code=command_set.language_code,
|
||||||
)
|
)
|
||||||
|
|
||||||
async def submit_photo(
|
async def submit_media(
|
||||||
self, id: str
|
self, id: str
|
||||||
) -> Tuple[Union[Message, None], Union[str, None]]:
|
) -> Tuple[Union[Message, None], Union[str, None]]:
|
||||||
db_entry = col_submitted.find_one({"_id": ObjectId(id)})
|
db_entry = col_submitted.find_one({"_id": ObjectId(id)})
|
||||||
@ -431,24 +437,47 @@ class PyroClient(Client):
|
|||||||
db_entry["user"], db_entry["telegram"]["msg_id"]
|
db_entry["user"], db_entry["telegram"]["msg_id"]
|
||||||
)
|
)
|
||||||
|
|
||||||
with open(str(filepath), "rb") as fh:
|
async with aiofiles.open(str(filepath), "rb") as fh:
|
||||||
photo_bytes = BytesIO(fh.read())
|
media_bytes = BytesIO(await fh.read())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
response = await photo_upload(
|
if db_entry["type"] == SubmissionType.PHOTO.value:
|
||||||
self.config["posting"]["api"]["album"],
|
response = await photo_upload(
|
||||||
client=client,
|
self.config["posting"]["api"]["album"],
|
||||||
multipart_data=BodyPhotoUploadAlbumsAlbumPhotosPost(
|
client=client,
|
||||||
File(photo_bytes, filepath.name, "image/jpeg")
|
multipart_data=BodyPhotoUpload(
|
||||||
),
|
File(media_bytes, filepath.name, "image/jpeg")
|
||||||
ignore_duplicates=self.config["submission"]["allow_duplicates"],
|
),
|
||||||
compress=False,
|
ignore_duplicates=self.config["submission"]["allow_duplicates"],
|
||||||
caption="queue",
|
compress=False,
|
||||||
)
|
caption="queue",
|
||||||
|
)
|
||||||
|
elif db_entry["type"] == SubmissionType.VIDEO.value:
|
||||||
|
response = await video_upload(
|
||||||
|
self.config["posting"]["api"]["album"],
|
||||||
|
client=client,
|
||||||
|
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,
|
||||||
|
multipart_data=BodyVideoUpload(
|
||||||
|
File(media_bytes, filepath.name, "video/*")
|
||||||
|
),
|
||||||
|
caption="queue",
|
||||||
|
)
|
||||||
except UnexpectedStatus:
|
except UnexpectedStatus:
|
||||||
raise SubmissionUnsupportedError(str(filepath))
|
raise SubmissionUnsupportedError(str(filepath))
|
||||||
|
|
||||||
response_dict = loads(response.content.decode("utf-8"))
|
response_dict = (
|
||||||
|
{}
|
||||||
|
if not hasattr(response, "content")
|
||||||
|
else loads(response.content.decode("utf-8"))
|
||||||
|
)
|
||||||
|
|
||||||
if "duplicates" in response_dict and len(response_dict["duplicates"]) > 0:
|
if "duplicates" in response_dict and len(response_dict["duplicates"]) > 0:
|
||||||
duplicates = []
|
duplicates = []
|
||||||
@ -480,7 +509,10 @@ class PyroClient(Client):
|
|||||||
except (FileNotFoundError, NotADirectoryError):
|
except (FileNotFoundError, NotADirectoryError):
|
||||||
logger.error("Could not delete '%s' on submission accepted", filepath)
|
logger.error("Could not delete '%s' on submission accepted", filepath)
|
||||||
|
|
||||||
return submission, response.parsed.id
|
return (
|
||||||
|
submission,
|
||||||
|
response.id if not hasattr(response, "parsed") else response.parsed.id,
|
||||||
|
)
|
||||||
|
|
||||||
async def ban_user(self, id: int) -> None:
|
async def ban_user(self, id: int) -> None:
|
||||||
pass
|
pass
|
||||||
|
@ -56,6 +56,11 @@
|
|||||||
"ignore_admins": true,
|
"ignore_admins": true,
|
||||||
"text": "#submitted"
|
"text": "#submitted"
|
||||||
},
|
},
|
||||||
|
"types": {
|
||||||
|
"photo": true,
|
||||||
|
"video": false,
|
||||||
|
"animation": false
|
||||||
|
},
|
||||||
"extensions": {
|
"extensions": {
|
||||||
"photo": [
|
"photo": [
|
||||||
"jpg",
|
"jpg",
|
||||||
|
@ -35,14 +35,26 @@ from photosapi_client.api.default.user_me_users_me_get import sync as user_me
|
|||||||
from photosapi_client.api.default.video_find_albums_album_videos_get import (
|
from photosapi_client.api.default.video_find_albums_album_videos_get import (
|
||||||
asyncio as video_find,
|
asyncio as video_find,
|
||||||
)
|
)
|
||||||
|
from photosapi_client.api.default.video_get_videos_id_get import asyncio as video_get
|
||||||
|
from photosapi_client.api.default.video_patch_videos_id_patch import (
|
||||||
|
asyncio as video_patch,
|
||||||
|
)
|
||||||
|
from photosapi_client.api.default.video_upload_albums_album_videos_post import (
|
||||||
|
asyncio as video_upload,
|
||||||
|
)
|
||||||
from photosapi_client.models.body_login_for_access_token_token_post import (
|
from photosapi_client.models.body_login_for_access_token_token_post import (
|
||||||
BodyLoginForAccessTokenTokenPost,
|
BodyLoginForAccessTokenTokenPost,
|
||||||
)
|
)
|
||||||
from photosapi_client.models.body_photo_upload_albums_album_photos_post import (
|
from photosapi_client.models.body_photo_upload_albums_album_photos_post import (
|
||||||
BodyPhotoUploadAlbumsAlbumPhotosPost,
|
BodyPhotoUploadAlbumsAlbumPhotosPost as BodyPhotoUpload,
|
||||||
|
)
|
||||||
|
from photosapi_client.models.body_video_upload_albums_album_videos_post import (
|
||||||
|
BodyVideoUploadAlbumsAlbumVideosPost as BodyVideoUpload,
|
||||||
)
|
)
|
||||||
from photosapi_client.models.http_validation_error import HTTPValidationError
|
from photosapi_client.models.http_validation_error import HTTPValidationError
|
||||||
|
from photosapi_client.models.photo import Photo
|
||||||
from photosapi_client.models.token import Token
|
from photosapi_client.models.token import Token
|
||||||
|
from photosapi_client.models.video import Video
|
||||||
from photosapi_client.types import File
|
from photosapi_client.types import File
|
||||||
|
|
||||||
from modules.http_client import http_session
|
from modules.http_client import http_session
|
||||||
|
@ -3,7 +3,7 @@ from datetime import datetime
|
|||||||
from os import makedirs, path
|
from os import makedirs, path
|
||||||
from random import choice
|
from random import choice
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
from traceback import format_exc
|
from traceback import format_exc, print_exc
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
|
|
||||||
import aiofiles
|
import aiofiles
|
||||||
@ -12,7 +12,16 @@ from photosapi_client.errors import UnexpectedStatus
|
|||||||
from PIL import Image
|
from PIL import Image
|
||||||
from pyrogram.client import Client
|
from pyrogram.client import Client
|
||||||
|
|
||||||
from modules.api_client import authorize, client, photo_find, photo_patch
|
from modules.api_client import (
|
||||||
|
authorize,
|
||||||
|
client,
|
||||||
|
photo_find,
|
||||||
|
photo_get,
|
||||||
|
photo_patch,
|
||||||
|
video_find,
|
||||||
|
video_get,
|
||||||
|
video_patch,
|
||||||
|
)
|
||||||
from modules.database import col_sent, col_submitted
|
from modules.database import col_sent, col_submitted
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -30,9 +39,19 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
pic = choice(
|
funcs = []
|
||||||
|
if app.config["posting"]["types"]["photo"]:
|
||||||
|
funcs.append(photo_find)
|
||||||
|
if (
|
||||||
|
app.config["posting"]["types"]["video"]
|
||||||
|
or app.config["posting"]["types"]["animation"]
|
||||||
|
):
|
||||||
|
funcs.append(video_find)
|
||||||
|
func = choice(funcs)
|
||||||
|
|
||||||
|
media = choice(
|
||||||
(
|
(
|
||||||
await photo_find(
|
await func(
|
||||||
album=app.config["posting"]["api"]["album"],
|
album=app.config["posting"]["api"]["album"],
|
||||||
caption="queue",
|
caption="queue",
|
||||||
page_size=app.config["posting"]["page_size"],
|
page_size=app.config["posting"]["page_size"],
|
||||||
@ -56,41 +75,48 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
response = await http_session.get(
|
try:
|
||||||
f"{app.config['posting']['api']['address']}/photos/{pic.id}",
|
if func is photo_find:
|
||||||
headers={"Authorization": f"Bearer {token}"},
|
response = await photo_get(id=media.id, client=client)
|
||||||
)
|
else:
|
||||||
|
response = await video_get(id=media.id, client=client)
|
||||||
if response.status != 200:
|
except Exception as exp:
|
||||||
|
print_exc()
|
||||||
logger.warning(
|
logger.warning(
|
||||||
app._("post_invalid_pic", "console").format(
|
"Media is invalid: %s",
|
||||||
response.status, str(await response.json())
|
exp
|
||||||
)
|
# app._("post_invalid_pic", "console").format(
|
||||||
|
# response.status, str(await response.json())
|
||||||
|
# )
|
||||||
)
|
)
|
||||||
if app.config["reports"]["error"]:
|
if app.config["reports"]["error"]:
|
||||||
await app.send_message(
|
await app.send_message(app.owner, f"Media is invalid: {exp}")
|
||||||
app.owner,
|
return
|
||||||
app._("post_invalid_pic", "message").format(
|
# await app.send_message(
|
||||||
response.status, await response.json()
|
# app.owner,
|
||||||
),
|
# app._("post_invalid_pic", "message").format(
|
||||||
)
|
# response.status, await response.json()
|
||||||
|
# ),
|
||||||
|
# )
|
||||||
|
|
||||||
tmp_dir = str(uuid4())
|
tmp_dir = str(uuid4())
|
||||||
|
|
||||||
makedirs(path.join(app.config["locations"]["tmp"], tmp_dir), exist_ok=True)
|
makedirs(path.join(app.config["locations"]["tmp"], tmp_dir), exist_ok=True)
|
||||||
|
|
||||||
tmp_path = path.join(tmp_dir, pic.filename)
|
tmp_path = path.join(tmp_dir, media.filename)
|
||||||
|
|
||||||
async with aiofiles.open(
|
async with aiofiles.open(
|
||||||
path.join(app.config["locations"]["tmp"], tmp_path), "wb"
|
path.join(app.config["locations"]["tmp"], tmp_path), "wb"
|
||||||
) as out_file:
|
) as out_file:
|
||||||
await out_file.write(await response.read())
|
await out_file.write(response.payload.read())
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Candidate {pic.filename} ({pic.id}) is {path.getsize(path.join(app.config['locations']['tmp'], tmp_path))} bytes big",
|
f"Candidate {media.filename} ({media.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:
|
if (
|
||||||
|
path.getsize(path.join(app.config["locations"]["tmp"], tmp_path)) > 5242880
|
||||||
|
) and func is photo_find:
|
||||||
image = Image.open(path.join(app.config["locations"]["tmp"], tmp_path))
|
image = Image.open(path.join(app.config["locations"]["tmp"], tmp_path))
|
||||||
width, height = image.size
|
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)
|
||||||
@ -110,7 +136,9 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
)
|
)
|
||||||
image.close()
|
image.close()
|
||||||
|
|
||||||
if path.getsize(path.join(app.config["locations"]["tmp"], tmp_path)) > 5242880:
|
if (
|
||||||
|
path.getsize(path.join(app.config["locations"]["tmp"], tmp_path)) > 5242880
|
||||||
|
) and func is photo_find:
|
||||||
rmtree(
|
rmtree(
|
||||||
path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True
|
path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True
|
||||||
)
|
)
|
||||||
@ -118,7 +146,7 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
|
|
||||||
del response
|
del response
|
||||||
|
|
||||||
submitted = col_submitted.find_one({"temp.file": pic.filename})
|
submitted = col_submitted.find_one({"temp.file": media.filename})
|
||||||
|
|
||||||
if submitted is not None and submitted["caption"] is not None:
|
if submitted is not None and submitted["caption"] is not None:
|
||||||
caption = submitted["caption"].strip()
|
caption = submitted["caption"].strip()
|
||||||
@ -150,14 +178,24 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
caption = caption
|
caption = caption
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sent = await app.send_photo(
|
if func is photo_find:
|
||||||
app.config["posting"]["channel"],
|
sent = await app.send_photo(
|
||||||
path.join(app.config["locations"]["tmp"], tmp_path),
|
app.config["posting"]["channel"],
|
||||||
caption=caption,
|
path.join(app.config["locations"]["tmp"], tmp_path),
|
||||||
disable_notification=app.config["posting"]["silent"],
|
caption=caption,
|
||||||
)
|
disable_notification=app.config["posting"]["silent"],
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
sent = await app.send_video(
|
||||||
|
app.config["posting"]["channel"],
|
||||||
|
path.join(app.config["locations"]["tmp"], tmp_path),
|
||||||
|
caption=caption,
|
||||||
|
disable_notification=app.config["posting"]["silent"],
|
||||||
|
)
|
||||||
except Exception as exp:
|
except Exception as exp:
|
||||||
logger.error(f"Could not send image {pic.filename} ({pic.id}) due to {exp}")
|
logger.error(
|
||||||
|
f"Could not send media {media.filename} ({media.id}) due to {exp}"
|
||||||
|
)
|
||||||
if app.config["reports"]["error"]:
|
if app.config["reports"]["error"]:
|
||||||
await app.send_message(
|
await app.send_message(
|
||||||
app.owner,
|
app.owner,
|
||||||
@ -169,8 +207,8 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
col_sent.insert_one(
|
col_sent.insert_one(
|
||||||
{
|
{
|
||||||
"date": datetime.now(),
|
"date": datetime.now(),
|
||||||
"image": pic.id,
|
"image": media.id,
|
||||||
"filename": pic.filename,
|
"filename": media.filename,
|
||||||
"channel": app.config["posting"]["channel"],
|
"channel": app.config["posting"]["channel"],
|
||||||
"caption": None
|
"caption": None
|
||||||
if (submitted is None or submitted["caption"] is None)
|
if (submitted is None or submitted["caption"] is None)
|
||||||
@ -178,13 +216,14 @@ async def send_content(app: Client, http_session: ClientSession) -> None:
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
await photo_patch(id=pic.id, client=client, caption="sent")
|
func_patch = photo_patch if func is photo_find else video_patch
|
||||||
|
await func_patch(id=media.id, client=client, caption="sent")
|
||||||
|
|
||||||
rmtree(path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True)
|
rmtree(path.join(app.config["locations"]["tmp"], tmp_dir), ignore_errors=True)
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
app._("post_sent", "console").format(
|
app._("post_sent", "console").format(
|
||||||
pic.id,
|
media.id,
|
||||||
str(app.config["posting"]["channel"]),
|
str(app.config["posting"]["channel"]),
|
||||||
caption.replace("\n", "%n"),
|
caption.replace("\n", "%n"),
|
||||||
str(app.config["posting"]["silent"]),
|
str(app.config["posting"]["silent"]),
|
||||||
|
@ -18,7 +18,7 @@ from ujson import loads
|
|||||||
|
|
||||||
from classes.pyroclient import PyroClient
|
from classes.pyroclient import PyroClient
|
||||||
from modules.api_client import (
|
from modules.api_client import (
|
||||||
BodyPhotoUploadAlbumsAlbumPhotosPost,
|
BodyPhotoUpload,
|
||||||
File,
|
File,
|
||||||
client,
|
client,
|
||||||
photo_delete,
|
photo_delete,
|
||||||
@ -158,7 +158,7 @@ async def cmd_import(app: PyroClient, msg: Message):
|
|||||||
uploaded = await photo_upload(
|
uploaded = await photo_upload(
|
||||||
app.config["posting"]["api"]["album"],
|
app.config["posting"]["api"]["album"],
|
||||||
client=client,
|
client=client,
|
||||||
multipart_data=BodyPhotoUploadAlbumsAlbumPhotosPost(
|
multipart_data=BodyPhotoUpload(
|
||||||
File(photo_bytes, Path(filename).name, "image/jpeg")
|
File(photo_bytes, Path(filename).name, "image/jpeg")
|
||||||
),
|
),
|
||||||
ignore_duplicates=app.config["submission"]["allow_duplicates"],
|
ignore_duplicates=app.config["submission"]["allow_duplicates"],
|
||||||
|
@ -215,7 +215,7 @@ async def get_submission(app: PyroClient, msg: Message):
|
|||||||
and app.config["submission"]["require_confirmation"]["admins"] is False
|
and app.config["submission"]["require_confirmation"]["admins"] is False
|
||||||
):
|
):
|
||||||
try:
|
try:
|
||||||
submitted = await app.submit_photo(str(inserted.inserted_id))
|
submitted = await app.submit_media(str(inserted.inserted_id))
|
||||||
await msg.reply_text(
|
await msg.reply_text(
|
||||||
app._("sub_yes_auto", "message", locale=user_locale),
|
app._("sub_yes_auto", "message", locale=user_locale),
|
||||||
disable_notification=True,
|
disable_notification=True,
|
||||||
|
Reference in New Issue
Block a user