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."""
try:
from ujson import dumps
except ModuleNotFoundError:
from json import dumps
import asyncio
from base64 import b64decode, b64encode
from ujson import dumps
from os import makedirs, path, sep
from random import choice
from typing import Tuple, Union
from aiohttp import ClientSession
from requests import get, patch, post
from classes.exceptions import SubmissionUploadError
from modules.logger import logWrite
from modules.utils import configGet
http_session = ClientSession(json_serialize=dumps, )
async def authorize() -> str:
makedirs(configGet("cache", "locations"), exist_ok=True)
if path.exists(configGet("cache", "locations")+sep+"api_access") is True:
with open(configGet("cache", "locations")+sep+"api_access", "rb") as file:
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
payload = {
"grant_type": "password",
@ -26,13 +35,13 @@ async def authorize() -> str:
"username": configGet("username", "posting", "api"),
"password": configGet("password", "posting", "api")
}
response = post(configGet("address", "posting", "api")+"/token", data=payload)
if response.status_code != 200:
logWrite(f'Incorrect API credentials! Could not login into "{configGet("address", "posting", "api")}" using login "{configGet("username", "posting", "api")}": HTTP {response.status_code}')
response = await http_session.post(configGet("address", "posting", "api")+"/token", data=payload)
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}')
raise ValueError
with open(configGet("cache", "locations")+sep+"api_access", "wb") as file:
file.write(b64encode(response.json()["access_token"].encode("utf-8")))
return response.json()["access_token"]
file.write(b64encode((await response.json())["access_token"].encode("utf-8")))
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.
@ -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
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}"})
if resp.status_code != 200:
logWrite(f'Could not get photos from album {configGet("album", "posting", "api")}: HTTP {resp.status_code}')
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)
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}"})
print(await resp.json(), flush=True)
if resp.status != 200:
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
if len(resp.json()["results"]) == 0:
if len((await resp.json())["results"]) == 0:
raise KeyError
pic = choice(resp.json()["results"])
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]:
@ -57,17 +67,17 @@ async def upload_pic(filepath: str, allow_duplicates: bool = False, token: Union
try:
pic_name = path.basename(filepath)
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)
if response.status_code != 200 and response.status_code != 409:
logWrite(f"Could not upload '{filepath}' to API: HTTP {response.status_code} with message '{response.content}'")
raise SubmissionUploadError(str(filepath), response.status_code, response.content)
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 != 200 and response.status != 409:
logWrite(f"Could not upload '{filepath}' to API: HTTP {response.status} with message '{response.content}'")
raise SubmissionUploadError(str(filepath), response.status, response.content)
duplicates = []
if "duplicates" in response.json():
for index, duplicate in enumerate(response.json()["duplicates"]):
if response.json()["access_token"] is None:
if "duplicates" in (await response.json()):
for index, duplicate in enumerate((await response.json())["duplicates"]):
if (await 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}')
duplicates.append(f'`{duplicate["id"]}`:\n{configGet("address_external", "posting", "api")}/token/photo/{(await response.json())["access_token"]}?id={index}')
return True, duplicates
except:
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]:
token = await authorize() if token is None else token
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())
if response.status_code != 200:
if response.status != 200:
return None
if len(response.json()["results"]) == 0:
if len((await response.json())["results"]) == 0:
return None
return response.json()["results"]
return (await response.json())["results"]
except Exception as exp:
logWrite(f"Could not find image with name '{name}' and caption '{caption}' due to: {exp}")
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:
token = await authorize() if token is None else token
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
except:
return False

View File

@ -6,9 +6,8 @@ from uuid import uuid4
from PIL import Image
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.logger import logWrite
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")))
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:
logWrite(locale("post_invalid_pic", "console", locale=configGet("locale")).format(response.status_code, str(response.json())))
if response.status != 200:
logWrite(locale("post_invalid_pic", "console", locale=configGet("locale")).format(response.status, str(response.json())))
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())
@ -50,7 +49,7 @@ async def send_content(app: PosterClient) -> None:
tmp_path = path.join(tmp_dir, pic[1])
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)

View File

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

View File

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