from http import HTTPStatus from ujson import loads from os import path, remove, sep from shutil import rmtree from typing import Tuple, Union from photosapi_client.models.body_photo_upload_albums_album_photos_post import ( BodyPhotoUploadAlbumsAlbumPhotosPost, ) from photosapi_client.types import File from photosapi_client.models.http_validation_error import HTTPValidationError import aiofiles from pyrogram.client import Client from pyrogram.types import Message from classes.exceptions import SubmissionDuplicatesError, SubmissionUnavailableError from modules.api_client import client, photo_upload from modules.database import col_submitted from bson import ObjectId from modules.logger import logWrite from modules.utils import configGet 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")] async def submit_photo( self, id: str ) -> Tuple[Union[Message, None], Union[str, None]]: db_entry = col_submitted.find_one({"_id": ObjectId(id)}) submission = None if db_entry is None: 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"], ) ): raise SubmissionUnavailableError() else: 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"] ) 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 ) except: raise SubmissionUnavailableError() logWrite(f"Uploading {path.basename(filepath)} to the API...", debug=True) async with aiofiles.open(filepath, "rb") as f: file_bytes = await f.read() response = await photo_upload( album=configGet("album", "posting", "api"), client=client, multipart_data=BodyPhotoUploadAlbumsAlbumPhotosPost( File(file_bytes, path.basename(filepath), "image/jpeg") ), ignore_duplicates=configGet("allow_duplicates", "submission"), caption="queue", compress=False, ) print(response, flush=True) if response.status_code == HTTPStatus.CONFLICT: duplicates = [] for index, duplicate in enumerate(loads(response.content)["duplicates"]): # type: ignore if loads(response.content)["access_token"] is None: 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/{loads(response.content)["access_token"]}?id={index}' ) raise SubmissionDuplicatesError(str(filepath), duplicates) 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, ) else: remove(str(filepath)) except (FileNotFoundError, NotADirectoryError): logWrite( f"Could not delete '{filepath}' on submission accepted", debug=True ) return submission, response.parsed.id async def ban_user(self, id: int) -> None: pass async def unban_user(self, id: int) -> None: pass