Optimized for API

This commit is contained in:
Profitroll 2023-01-17 14:11:23 +01:00
parent 9f0ed202da
commit aebe804b58
7 changed files with 156 additions and 36 deletions

View File

@ -25,6 +25,7 @@
"location": "logs"
},
"locations": {
"tmp": "tmp",
"data": "data",
"cache": "cache",
"sent": "data/sent",
@ -67,10 +68,7 @@
"address": "http://localhost:8054",
"username": "",
"password": "",
"albums": {
"queue": "poster_queue",
"sent": "poster_sent"
}
"album": ""
}
},
"caption": {

View File

@ -19,6 +19,9 @@
"sub_by": "\n\nSubmitted by:",
"sub_sent": "Media has been submitted.\nWe'll notify you whether it will be accepted or not soon.",
"sub_cooldown": "You can only submit 1 media per {0} seconds",
"sub_media_failed": "Could not upload submission to API. Please check logs for details.",
"sub_media_duplicates": "⚠️ Image duplicates found",
"sub_media_duplicates_list": "It seems like following image has duplicates in API's Db.\n\nNext files marked as similar:\n • {0}",
"document_too_large": "File you've sent is too large. Please submit files not bigger than {0} MB",
"mime_not_allowed": "File type not allowed. Please, consider using one of these: {0}",
"post_exception": "Could not send content due to `{exp}`\n\nTraceback:\n```{0}```",

View File

@ -19,6 +19,9 @@
"sub_by": "\n\nПредставлено:",
"sub_sent": "Медіа-файл надіслано.\nСкоро ми повідомимо вас, чи буде його прийнято.",
"sub_cooldown": "Ви можете надсилати лише 1 медіафайл на {0} секунд",
"sub_media_failed": "Не вдалося завантажити подання на сервер. Перевірте логи для деталей.",
"sub_media_duplicates": "⚠️ Знайдено зображення-дублікати",
"sub_media_duplicates_list": "Здається, подане зображення має дублікати в базі даних.\n\nНаступні файли було відмічено як дуже схожі з поданням:\n • {0}",
"document_too_large": "Надісланий файл завеликий. Будь ласка, надсилайте файли не більше {0} Мб",
"mime_not_allowed": "Тип файлу не дозволений. Розгляньте можливість використання одного з цих: {0}",
"post_exception": "Не вдалося надіслати контент через `{exp}`\n\nTraceback:\n```{0}```",

60
modules/api_client.py Normal file
View File

@ -0,0 +1,60 @@
from os import makedirs, path, sep
from base64 import b64encode, b64decode
from random import choice
from typing import Tuple
from requests import get, post, put, patch
from modules.utils import configGet
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 "user" in get(configGet("address", "posting", "api")+"/users/me/", headers={"Authorization": f"Bearer {token}"}).json():
return token
payload = {
"grant_type": "password",
"scope": "me albums.list albums.read albums.write photos.list photos.read photos.write videos.list videos.read videos.write",
"username": configGet("username", "posting", "api"),
"password": configGet("password", "posting", "api")
}
response = post(configGet("address", "posting", "api")+"/token", data=payload).json()
with open(configGet("cache", "locations")+sep+"api_access", "wb") as file:
file.write(b64encode(response["access_token"].encode("utf-8")))
return response["access_token"]
def random_pic() -> 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 = authorize()
pic = choice(get(f'{configGet("address", "posting", "api")}/albums/{configGet("album", "posting", "api")}/photos?q=&page_size=100&caption=queue', headers={"Authorization": f"Bearer {token}"}).json()["results"])
return pic["id"], pic["filename"]
def upload_pic(filepath: str) -> bool:
token = authorize()
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&caption=queue', headers={"Authorization": f"Bearer {token}"}, files=files).json()
print(response, flush=True)
duplicates = []
if "duplicates" in response:
for duplicate in response["duplicates"]:
duplicates.append(f'{configGet("address", "posting", "api")}/photos/{duplicate["id"]}')
return True, duplicates
except:
return False, []
def move_pic(id: str) -> bool:
token = authorize()
try:
patch(f'{configGet("address", "posting", "api")}/photos/{id}?caption=sent', headers={"Authorization": f"Bearer {token}"})
return True
except:
return False
if __name__ == "__main__":
print(authorize())

View File

@ -3,6 +3,7 @@ from pathlib import Path
from pyrogram import filters
from pyrogram.client import Client
from pyrogram.types import CallbackQuery
from modules.api_client import upload_pic
from modules.utils import jsonLoad, jsonSave, configGet, locale
from modules.submissions import subBlock, subUnblock
from modules.app import app
@ -18,11 +19,25 @@ async def callback_query_yes(app: Client, clb: CallbackQuery):
await clb.answer(text=locale("sub_msg_unavail", "message", locale=user_locale), show_alert=True)
return
try:
media = await app.download_media(submission, file_name=configGet("queue", "locations")+sep)
if clb.data.endswith("_caption"):
index = jsonLoad(configGet("index", "locations"))
index["captions"][Path(media).name] = submission.caption
jsonSave(index, configGet("index", "locations"))
if configGet("api_based", "mode") is True:
media = await app.download_media(submission, file_name=configGet("tmp", "locations")+sep)
upload = upload_pic(media)
if upload[0] is False:
await clb.answer(text=locale("sub_media_failed", "message", locale=user_locale), show_alert=True)
elif len(upload[1]) > 0:
await clb.answer(text=locale("sub_media_duplicates", "message", locale=user_locale))
await clb.message.reply_text(locale("sub_media_duplicates_list", "message", locale=user_locale).format("\n".join(upload[1])))
else:
if clb.data.endswith("_caption"):
index = jsonLoad(configGet("index", "locations"))
index["captions"][Path(media).name] = submission.caption
jsonSave(index, configGet("index", "locations"))
else:
media = await app.download_media(submission, file_name=configGet("queue", "locations")+sep)
if clb.data.endswith("_caption"):
index = jsonLoad(configGet("index", "locations"))
index["captions"][Path(media).name] = submission.caption
jsonSave(index, configGet("index", "locations"))
except:
await clb.answer(text=locale("sub_media_unavail", "message", locale=user_locale), show_alert=True)
return

View File

@ -1,10 +1,12 @@
from os import listdir, sep
from os import listdir, remove, sep
from random import choice
from shutil import move
from shutil import copyfileobj, move
from requests import get
from traceback import format_exc
from pyrogram.client import Client
from pyrogram.types import InlineKeyboardMarkup, InlineKeyboardButton
from modules.logger import logWrite
from modules.api_client import authorize, move_pic, random_pic
from modules.utils import jsonLoad, jsonSave, configGet, locale
async def send_content(app: Client):
@ -13,40 +15,66 @@ async def send_content(app: Client):
try:
index = jsonLoad(configGet("index", "locations"))
list_queue = listdir(configGet("queue", "locations"))
for file in list_queue:
if configGet("api_based", "mode"):
if not file in index["sent"]:
try:
pic = random_pic()
except:
logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
await app.send_message(configGet("admin"), locale("post_empty", "message", locale=configGet("locale")))
return
ext_match = False
token = authorize()
for ext in configGet("photo", "posting", "extensions"):
if file.endswith(ext):
ext_match = True
ext_type = "photo"
break
response = get(f'{configGet("address", "posting", "api")}/photos/{pic[0]}', headers={"Authorization": f"Bearer {token}"}, stream=True)
for ext in configGet("video", "posting", "extensions"):
if file.endswith(ext):
ext_match = True
ext_type = "video"
break
with open(configGet("tmp", "locations")+sep+pic[0]+".jpg", 'wb') as out_file:
copyfileobj(response.raw, out_file)
if not ext_match:
del response
candidate = configGet("tmp", "locations")+sep+pic[0]+".jpg"
candidate_file = pic[1]
ext_type = "photo"
if not configGet("api_based", "mode"):
list_queue = listdir(configGet("queue", "locations"))
for file in list_queue:
if not file in index["sent"]:
ext_match = False
for ext in configGet("photo", "posting", "extensions"):
if file.endswith(ext):
ext_match = True
ext_type = "photo"
break
for ext in configGet("video", "posting", "extensions"):
if file.endswith(ext):
ext_match = True
ext_type = "video"
break
if not ext_match:
list_queue.remove(file)
else:
list_queue.remove(file)
if len(list_queue) > 0:
candidate_file = choice(list_queue)
candidate = configGet("queue", "locations")+sep+candidate_file
else:
list_queue.remove(file)
if len(list_queue) > 0:
candidate_file = choice(list_queue)
candidate = configGet("queue", "locations")+sep+candidate_file
else:
logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
await app.send_message(configGet("admin"), locale("post_empty", "message", locale=configGet("locale")))
return
logWrite(locale("post_empty", "console", locale=configGet("locale")))
if configGet("error", "reports"):
await app.send_message(configGet("admin"), locale("post_empty", "message", locale=configGet("locale")))
return
if candidate_file in index["captions"]:
caption = index["captions"][candidate_file]
@ -84,6 +112,10 @@ async def send_content(app: Client):
else:
return
if configGet("api_based", "mode"):
remove(configGet("tmp", "locations")+sep+pic[0]+".jpg")
move_pic(pic[0])
index["sent"].append(candidate_file)
index["last_id"] = sent.id

View File

@ -70,6 +70,7 @@ if args.norun:
try:
from modules.app import app
from pyrogram import idle
from requests import get, post
except ModuleNotFoundError:
print(locale("deps_missing", "console", locale=configGet("locale")), flush=True)
exit()
@ -122,6 +123,9 @@ if configGet("submit", "mode"):
from modules.callbacks.submission import *
from modules.commands.mode_submit import *
from modules.handlers.submission import *
if configGet("api_based", "mode"):
from modules.api_client import authorize
#===========================================================================================================================================
# Work in progress
@ -147,6 +151,11 @@ if __name__ == "__main__":
if configGet("post", "mode"):
scheduler.start()
if configGet("api_based", "mode"):
token = authorize()
if len(get(f'{configGet("address", "posting", "api")}/albums?q={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"}).json()["results"]) == 0:
post(f'{configGet("address", "posting", "api")}/albums?name={configGet("queue", "posting", "api", "albums")}&title={configGet("queue", "posting", "api", "albums")}', headers={"Authorization": f"Bearer {token}"})
idle()
app.send_message(configGet("admin"), locale("shutdown", "message", locale=configGet("locale")).format(str(pid)))