diff --git a/classes/poster_client.py b/classes/poster_client.py index ba0aace..94be2c6 100644 --- a/classes/poster_client.py +++ b/classes/poster_client.py @@ -1,10 +1,19 @@ from os import path, remove, sep from shutil import rmtree from typing import Tuple, Union +from photosapi_client.api.default.photo_upload_albums_album_photos_post import ( + asyncio as upload_pic, +) +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 upload_pic +from modules.api_client import client from modules.database import col_submitted from bson import ObjectId from modules.logger import logWrite @@ -61,12 +70,26 @@ class PosterClient(Client): 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 upload_pic( - str(filepath), allow_duplicates=configGet("allow_duplicates", "submission") + 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, ) - if len(response[1]) > 0: - raise SubmissionDuplicatesError(str(filepath), response[1]) + if isinstance(response, HTTPValidationError) > 0: + raise SubmissionDuplicatesError( + str(filepath), response.to_dict()["duplicates"] + ) col_submitted.find_one_and_update( {"_id": ObjectId(id)}, {"$set": {"done": True}} diff --git a/modules/api_client.py b/modules/api_client.py index d7cf50b..49baa60 100644 --- a/modules/api_client.py +++ b/modules/api_client.py @@ -1,23 +1,27 @@ """This is only a temporary solution. Complete Photos API client is yet to be developed.""" -import asyncio +from photosapi_client import AuthenticatedClient + +# import asyncio from base64 import b64decode, b64encode from os import makedirs, path, sep -from random import choice -from traceback import print_exc -from typing import Tuple, Union + +# from random import choice +# from traceback import print_exc +# from typing import Tuple, Union import aiofiles -from aiohttp import FormData -from classes.exceptions import ( - AlbumCreationDuplicateError, - AlbumCreationError, - AlbumCreationNameError, - SubmissionUploadError, - UserCreationDuplicateError, - UserCreationError, -) +# from aiohttp import FormData + +# from classes.exceptions import ( +# AlbumCreationDuplicateError, +# AlbumCreationError, +# AlbumCreationNameError, +# SubmissionUploadError, +# UserCreationDuplicateError, +# UserCreationError, +# ) from modules.logger import logWrite from modules.utils import configGet, locale from modules.http_client import http_session @@ -68,196 +72,200 @@ async def authorize() -> str: 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. +client = AuthenticatedClient( + base_url=configGet("address", "posting", "api"), token=await authorize() +) - ### Returns: - * `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( - locale("random_pic_response", "console", locale=configGet("locale_log")).format( - await resp.json() - ), - debug=True, - ) - if resp.status != 200: - logWrite( - locale( - "random_pic_error_code", - "console", - locale=configGet("locale_log").format( - configGet("album", "posting", "api"), resp.status - ), - ), - ) - logWrite( - locale( - "random_pic_error_debug", - "console", - locale=configGet("locale_log").format( - configGet("address", "posting", "api"), - configGet("album", "posting", "api"), - configGet("page_size", "posting"), - token, - 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 random_pic(token: Union[str, None] = None) -> Tuple[str, str]: +# """Returns random image id and filename from the queue. + +# ### Returns: +# * `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( +# locale("random_pic_response", "console", locale=configGet("locale_log")).format( +# await resp.json() +# ), +# debug=True, +# ) +# if resp.status != 200: +# logWrite( +# locale( +# "random_pic_error_code", +# "console", +# locale=configGet("locale_log").format( +# configGet("album", "posting", "api"), resp.status +# ), +# ), +# ) +# logWrite( +# locale( +# "random_pic_error_debug", +# "console", +# locale=configGet("locale_log").format( +# configGet("address", "posting", "api"), +# configGet("album", "posting", "api"), +# configGet("page_size", "posting"), +# token, +# 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, Union[str, None]]: - token = await authorize() if token is None else token - try: - pic_name = path.basename(filepath) - logWrite(f"Uploading {pic_name} to the API...", debug=True) - 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" - ) - 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(), - }, - headers={"Authorization": f"Bearer {token}"}, - data=formdata, - ) - response_json = await response.json() - if response.status != 200 and response.status != 409: - logWrite( - locale( - "pic_upload_error", - "console", - locale=configGet("locale_log").format( - filepath, response.status, response.content - ), - ), - ) - raise SubmissionUploadError( - str(filepath), response.status, response.content - ) - id = response_json["id"] if "id" in await response.json() else None - duplicates = [] - if "duplicates" in response_json: - for index, duplicate in enumerate(response_json["duplicates"]): # type: ignore - if response_json["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/{response_json["access_token"]}?id={index}' - ) - return True, duplicates, id - except Exception as exp: - print_exc() - return False, [], None +# async def upload_pic( +# filepath: str, allow_duplicates: bool = False, token: Union[str, None] = None +# ) -> Tuple[bool, list, Union[str, None]]: +# token = await authorize() if token is None else token +# try: +# pic_name = path.basename(filepath) +# logWrite(f"Uploading {pic_name} to the API...", debug=True) +# 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" +# ) +# 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(), +# }, +# headers={"Authorization": f"Bearer {token}"}, +# data=formdata, +# ) +# response_json = await response.json() +# if response.status != 200 and response.status != 409: +# logWrite( +# locale( +# "pic_upload_error", +# "console", +# locale=configGet("locale_log").format( +# filepath, response.status, response.content +# ), +# ), +# ) +# raise SubmissionUploadError( +# str(filepath), response.status, response.content +# ) +# id = response_json["id"] if "id" in await response.json() else None +# duplicates = [] +# if "duplicates" in response_json: +# for index, duplicate in enumerate(response_json["duplicates"]): # type: ignore +# if response_json["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/{response_json["access_token"]}?id={index}' +# ) +# return True, duplicates, id +# except Exception as exp: +# print_exc() +# return False, [], 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}"}, - ) - # logWrite(response.json()) - if response.status != 200: - return None - if len((await response.json())["results"]) == 0: - return None - return (await response.json())["results"] - except Exception as exp: - logWrite( - locale( - "find_pic_error", - "console", - locale=configGet("locale_log").format(name, caption, exp), - ), - ) - return 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}"}, +# ) +# # logWrite(response.json()) +# if response.status != 200: +# return None +# if len((await response.json())["results"]) == 0: +# return None +# return (await response.json())["results"] +# except Exception as exp: +# logWrite( +# locale( +# "find_pic_error", +# "console", +# locale=configGet("locale_log").format(name, caption, 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: - response = await http_session.patch( - f'{configGet("address", "posting", "api")}/photos/{id}?caption=sent', - headers={"Authorization": f"Bearer {token}"}, - ) - if response.status != 200: - logWrite(f"Media moving failed with HTTP {response.status}", debug=True) - return False - return True - except: - return False +# async def move_pic(id: str, token: Union[str, None] = None) -> bool: +# token = await authorize() if token is None else token +# try: +# response = await http_session.patch( +# f'{configGet("address", "posting", "api")}/photos/{id}?caption=sent', +# headers={"Authorization": f"Bearer {token}"}, +# ) +# if response.status != 200: +# logWrite(f"Media moving failed with HTTP {response.status}", debug=True) +# return False +# return True +# except: +# return False -async def remove_pic(id: str, token: Union[str, None] = None) -> bool: - token = await authorize() if token is None else token - try: - response = await http_session.delete( - f'{configGet("address", "posting", "api")}/photos/{id}', - headers={"Authorization": f"Bearer {token}"}, - ) - if response.status != 204: - logWrite(f"Media removal failed with HTTP {response.status}", debug=True) - return False - return True - except: - return False +# async def remove_pic(id: str, token: Union[str, None] = None) -> bool: +# token = await authorize() if token is None else token +# try: +# response = await http_session.delete( +# f'{configGet("address", "posting", "api")}/photos/{id}', +# headers={"Authorization": f"Bearer {token}"}, +# ) +# if response.status != 204: +# logWrite(f"Media removal failed with HTTP {response.status}", debug=True) +# return False +# return True +# except: +# return False -async def create_user(username: str, email: str, password: str) -> None: - response = await http_session.post( - f'{configGet("address", "posting", "api")}/users', - data={"user": username, "email": email, "password": password}, - ) - if response.status == 409: - raise UserCreationDuplicateError(username) - elif response.status != 204: - raise UserCreationError(response.status, await response.text(encoding="utf-8")) - return None +# async def create_user(username: str, email: str, password: str) -> None: +# response = await http_session.post( +# f'{configGet("address", "posting", "api")}/users', +# data={"user": username, "email": email, "password": password}, +# ) +# if response.status == 409: +# raise UserCreationDuplicateError(username) +# elif response.status != 204: +# raise UserCreationError(response.status, await response.text(encoding="utf-8")) +# return None -async def create_album(name: str, title: str) -> None: - token = await authorize() - response = await http_session.post( - f'{configGet("address", "posting", "api")}/albums', - params={"name": name, "title": title}, - headers={"Authorization": f"Bearer {token}"}, - ) - if response.status == 409: - raise AlbumCreationDuplicateError(name) - elif response.status == 406: - raise AlbumCreationNameError(await response.json()) - elif response.status != 200: - raise AlbumCreationError(response.status, await response.text(encoding="utf-8")) - return None +# async def create_album(name: str, title: str) -> None: +# token = await authorize() +# response = await http_session.post( +# f'{configGet("address", "posting", "api")}/albums', +# params={"name": name, "title": title}, +# headers={"Authorization": f"Bearer {token}"}, +# ) +# if response.status == 409: +# raise AlbumCreationDuplicateError(name) +# elif response.status == 406: +# raise AlbumCreationNameError(await response.json()) +# elif response.status != 200: +# raise AlbumCreationError(response.status, await response.text(encoding="utf-8")) +# return None -if __name__ == "__main__": - print(asyncio.run(authorize())) +# if __name__ == "__main__": +# print(asyncio.run(authorize())) diff --git a/requirements.txt b/requirements.txt index a50f2cf..b0548ab 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ +photosapi_client==0.1.1 python_dateutil==2.8.2 apscheduler~=3.10.1 pytimeparse~=1.1.8 @@ -5,7 +6,7 @@ convopyro==0.5 pyrogram~=2.0.102 aiofiles~=23.1.0 aiohttp~=3.8.4 -psutil~=5.9.4 pymongo~=4.3.3 +psutil~=5.9.4 pillow~=9.4.0 ujson~=5.7.0 \ No newline at end of file