dev #19

Merged
profitroll merged 98 commits from dev into master 2023-04-24 13:48:22 +03:00
4 changed files with 44 additions and 36 deletions
Showing only changes of commit a913ba19c6 - Show all commits

View File

@ -1,24 +1,33 @@
"""This is only a temporary solution. Complete Photos API client is yet to be developed.""" """This is only a temporary solution. Complete Photos API client is yet to be developed."""
try:
from ujson import dumps
except ModuleNotFoundError:
from json import dumps
import asyncio import asyncio
from base64 import b64decode, b64encode from base64 import b64decode, b64encode
from ujson import dumps
from os import makedirs, path, sep from os import makedirs, path, sep
from random import choice from random import choice
from typing import Tuple, Union from typing import Tuple, Union
from aiohttp import ClientSession
from requests import get, patch, post
from classes.exceptions import SubmissionUploadError from classes.exceptions import SubmissionUploadError
from modules.logger import logWrite from modules.logger import logWrite
from modules.utils import configGet from modules.utils import configGet
http_session = ClientSession(json_serialize=dumps, )
async def authorize() -> str: async def authorize() -> str:
makedirs(configGet("cache", "locations"), exist_ok=True) makedirs(configGet("cache", "locations"), exist_ok=True)
if path.exists(configGet("cache", "locations")+sep+"api_access") is True: if path.exists(configGet("cache", "locations")+sep+"api_access") is True:
with open(configGet("cache", "locations")+sep+"api_access", "rb") as file: with open(configGet("cache", "locations")+sep+"api_access", "rb") as file:
token = b64decode(file.read()).decode("utf-8") token = b64decode(file.read()).decode("utf-8")
if get(configGet("address", "posting", "api")+"/users/me/", headers={"Authorization": f"Bearer {token}"}).status_code == 200: if (await http_session.get(configGet("address", "posting", "api")+"/users/me/", headers={"Authorization": f"Bearer {token}"})).status == 200:
return token return token
payload = { payload = {
"grant_type": "password", "grant_type": "password",
@ -26,13 +35,13 @@ async def authorize() -> str:
"username": configGet("username", "posting", "api"), "username": configGet("username", "posting", "api"),
"password": configGet("password", "posting", "api") "password": configGet("password", "posting", "api")
} }
response = post(configGet("address", "posting", "api")+"/token", data=payload) response = await http_session.post(configGet("address", "posting", "api")+"/token", data=payload)
if response.status_code != 200: if response.status != 200:
logWrite(f'Incorrect API credentials! Could not login into "{configGet("address", "posting", "api")}" using login "{configGet("username", "posting", "api")}": HTTP {response.status_code}') logWrite(f'Incorrect API credentials! Could not login into "{configGet("address", "posting", "api")}" using login "{configGet("username", "posting", "api")}": HTTP {response.status}')
raise ValueError raise ValueError
with open(configGet("cache", "locations")+sep+"api_access", "wb") as file: with open(configGet("cache", "locations")+sep+"api_access", "wb") as file:
file.write(b64encode(response.json()["access_token"].encode("utf-8"))) file.write(b64encode((await response.json())["access_token"].encode("utf-8")))
return response.json()["access_token"] return (await response.json())["access_token"]
async def random_pic(token: Union[str, None] = None) -> Tuple[str, str]: async def random_pic(token: Union[str, None] = None) -> Tuple[str, str]:
"""Returns random image id and filename from the queue. """Returns random image id and filename from the queue.
@ -42,14 +51,15 @@ async def random_pic(token: Union[str, None] = None) -> Tuple[str, str]:
""" """
token = await authorize() if token is None else token 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') logWrite(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size={configGet("page_size", "posting")}&caption=queue')
resp = 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}"}) 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}"})
if resp.status_code != 200: print(await resp.json(), flush=True)
logWrite(f'Could not get photos from album {configGet("album", "posting", "api")}: HTTP {resp.status_code}') if resp.status != 200:
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_code}', 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 raise ValueError
if len(resp.json()["results"]) == 0: if len((await resp.json())["results"]) == 0:
raise KeyError raise KeyError
pic = choice(resp.json()["results"]) pic = choice((await resp.json())["results"])
return pic["id"], pic["filename"] 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]:
@ -57,17 +67,17 @@ async def upload_pic(filepath: str, allow_duplicates: bool = False, token: Union
try: try:
pic_name = path.basename(filepath) pic_name = path.basename(filepath)
files = {'file': (pic_name, open(filepath, 'rb'), 'image/jpeg')} files = {'file': (pic_name, open(filepath, 'rb'), 'image/jpeg')}
response = post(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos', params={"caption": "queue", "compress": False, "ignore_duplicates": allow_duplicates}, headers={"Authorization": f"Bearer {token}"}, files=files) response = await http_session.post(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos', params={"caption": "queue", "compress": False, "ignore_duplicates": allow_duplicates}, headers={"Authorization": f"Bearer {token}"}, files=files)
if response.status_code != 200 and response.status_code != 409: if response.status != 200 and response.status != 409:
logWrite(f"Could not upload '{filepath}' to API: HTTP {response.status_code} with message '{response.content}'") logWrite(f"Could not upload '{filepath}' to API: HTTP {response.status} with message '{response.content}'")
raise SubmissionUploadError(str(filepath), response.status_code, response.content) raise SubmissionUploadError(str(filepath), response.status, response.content)
duplicates = [] duplicates = []
if "duplicates" in response.json(): if "duplicates" in (await response.json()):
for index, duplicate in enumerate(response.json()["duplicates"]): for index, duplicate in enumerate((await response.json())["duplicates"]):
if response.json()["access_token"] is None: 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: else:
duplicates.append(f'`{duplicate["id"]}`:\n{configGet("address_external", "posting", "api")}/token/photo/{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 return True, duplicates
except: except:
return False, [] return False, []
@ -75,13 +85,13 @@ async def upload_pic(filepath: str, allow_duplicates: bool = False, token: Union
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 token = await authorize() if token is None else token
try: try:
response = 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()) # logWrite(response.json())
if response.status_code != 200: if response.status != 200:
return None return None
if len(response.json()["results"]) == 0: if len((await response.json())["results"]) == 0:
return None return None
return response.json()["results"] return (await response.json())["results"]
except Exception as exp: 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 return None
@ -89,7 +99,7 @@ async def find_pic(name: str, caption: Union[str, None] = None, token: Union[str
async def move_pic(id: str, token: Union[str, None] = None) -> bool: async def move_pic(id: str, token: Union[str, None] = None) -> bool:
token = await authorize() if token is None else token token = await authorize() if token is None else token
try: try:
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 return True
except: except:
return False return False

View File

@ -6,9 +6,8 @@ from uuid import uuid4
from PIL import Image from PIL import Image
from classes.poster_client import PosterClient from classes.poster_client import PosterClient
from requests import get
from modules.api_client import authorize, move_pic, random_pic from modules.api_client import authorize, move_pic, random_pic, http_session
from modules.database import col_sent, col_submitted from modules.database import col_sent, col_submitted
from modules.logger import logWrite from modules.logger import logWrite
from modules.utils import configGet, locale from modules.utils import configGet, locale
@ -36,12 +35,12 @@ async def send_content(app: PosterClient) -> None:
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 return
response = get(f'{configGet("address", "posting", "api")}/photos/{pic[0]}', headers={"Authorization": f"Bearer {token}"}, stream=True) response = await http_session.get(f'{configGet("address", "posting", "api")}/photos/{pic[0]}', headers={"Authorization": f"Bearer {token}"}, stream=True)
if response.status_code != 200: if response.status != 200:
logWrite(locale("post_invalid_pic", "console", locale=configGet("locale")).format(response.status_code, str(response.json()))) logWrite(locale("post_invalid_pic", "console", locale=configGet("locale")).format(response.status, str(response.json())))
if configGet("error", "reports"): if configGet("error", "reports"):
await app.send_message(app.owner, locale("post_invalid_pic", "message", locale=configGet("locale")).format(response.status_code, 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()) tmp_dir = str(uuid4())
@ -50,7 +49,7 @@ async def send_content(app: PosterClient) -> None:
tmp_path = path.join(tmp_dir, pic[1]) tmp_path = path.join(tmp_dir, pic[1])
with open(path.join(configGet("tmp", "locations"), tmp_path), 'wb') as out_file: with open(path.join(configGet("tmp", "locations"), tmp_path), 'wb') as out_file:
copyfileobj(response.raw, out_file) 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)

View File

@ -70,7 +70,6 @@ if args.norun:
try: try:
from modules.app import app from modules.app import app
from pyrogram.sync import idle from pyrogram.sync import idle
from requests import get, post
except ModuleNotFoundError: except ModuleNotFoundError:
print(locale("deps_missing", "console", locale=configGet("locale")), flush=True) print(locale("deps_missing", "console", locale=configGet("locale")), flush=True)
exit() exit()

View File

@ -1,6 +1,6 @@
apscheduler~=3.10.0 apscheduler~=3.10.0
pyrogram~=2.0.99 pyrogram~=2.0.100
requests~=2.28.2 aiohttp~=3.8.4
psutil~=5.9.4 psutil~=5.9.4
pymongo~=4.3.3 pymongo~=4.3.3
pillow~=9.4.0 pillow~=9.4.0